1/* 2 * "$Id: print-vars.c,v 1.91 2010/12/05 21:38:15 rlk Exp $" 3 * 4 * Print plug-in driver utility functions for the GIMP. 5 * 6 * Copyright 1997-2000 Michael Sweet (mike@easysw.com) and 7 * Robert Krawitz (rlk@alum.mit.edu) 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the Free 11 * Software Foundation; either version 2 of the License, or (at your option) 12 * any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 * for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 */ 23 24/* 25 * This file must include only standard C header files. The core code must 26 * compile on generic platforms that don't support glib, gimp, gtk, etc. 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <math.h> 33#ifdef HAVE_LIMITS_H 34#include <limits.h> 35#endif 36#include <string.h> 37#include <gutenprint/gutenprint.h> 38#include "gutenprint-internal.h" 39#include <gutenprint/gutenprint-intl-internal.h> 40#include "generic-options.h" 41 42typedef struct 43{ 44 char *name; 45 stp_parameter_type_t typ; 46 stp_parameter_activity_t active; 47 union 48 { 49 int ival; 50 int bval; 51 double dval; 52 stp_curve_t *cval; 53 stp_array_t *aval; 54 stp_raw_t rval; 55 } value; 56} value_t; 57 58struct stp_compdata 59{ 60 char *name; 61 stp_copy_data_func_t copyfunc; 62 stp_free_data_func_t freefunc; 63 void *data; 64}; 65 66struct stp_vars /* Plug-in variables */ 67{ 68 char *driver; /* Name of printer "driver" */ 69 char *color_conversion; /* Color module in use */ 70 int left; /* Offset from left-upper corner, points */ 71 int top; /* ... */ 72 int width; /* Width of the image, points */ 73 int height; /* ... */ 74 int page_width; /* Width of page in points */ 75 int page_height; /* Height of page in points */ 76 stp_list_t *params[STP_PARAMETER_TYPE_INVALID]; 77 stp_list_t *internal_data; 78 void (*outfunc)(void *data, const char *buffer, size_t bytes); 79 void *outdata; 80 void (*errfunc)(void *data, const char *buffer, size_t bytes); 81 void *errdata; 82 int verified; /* Ensure that params are OK! */ 83}; 84 85static int standard_vars_initialized = 0; 86 87 88void 89stp_parameter_description_destroy(stp_parameter_t *desc) 90{ 91 switch (desc->p_type) 92 { 93 case STP_PARAMETER_TYPE_CURVE: 94 if (desc->bounds.curve) 95 stp_curve_destroy(desc->bounds.curve); 96 desc->bounds.curve = NULL; 97 break; 98 case STP_PARAMETER_TYPE_ARRAY: 99 if (desc->bounds.array) 100 stp_array_destroy(desc->bounds.array); 101 desc->bounds.array = NULL; 102 break; 103 case STP_PARAMETER_TYPE_STRING_LIST: 104 if (desc->bounds.str) 105 stp_string_list_destroy(desc->bounds.str); 106 desc->bounds.str = NULL; 107 break; 108 default: 109 break; 110 } 111} 112static stp_vars_t default_vars; 113 114#define CHECK_VARS(v) STPI_ASSERT(v, NULL) 115 116static const char * 117value_namefunc(const void *item) 118{ 119 const value_t *v = (const value_t *) (item); 120 return v->name; 121} 122 123static void 124value_freefunc(void *item) 125{ 126 value_t *v = (value_t *) (item); 127 switch (v->typ) 128 { 129 case STP_PARAMETER_TYPE_STRING_LIST: 130 case STP_PARAMETER_TYPE_FILE: 131 case STP_PARAMETER_TYPE_RAW: 132 stp_free((void *) v->value.rval.data); 133 break; 134 case STP_PARAMETER_TYPE_CURVE: 135 if (v->value.cval) 136 stp_curve_destroy(v->value.cval); 137 break; 138 case STP_PARAMETER_TYPE_ARRAY: 139 stp_array_destroy(v->value.aval); 140 break; 141 default: 142 break; 143 } 144 stp_free(v->name); 145 stp_free(v); 146} 147 148static stp_list_t * 149create_vars_list(void) 150{ 151 stp_list_t *ret = stp_list_create(); 152 stp_list_set_freefunc(ret, value_freefunc); 153 stp_list_set_namefunc(ret, value_namefunc); 154 return ret; 155} 156 157static void 158copy_to_raw(stp_raw_t *raw, const void *data, size_t bytes) 159{ 160 char *ndata = NULL; 161 if (data) 162 { 163 ndata = stp_malloc(bytes + 1); 164 memcpy(ndata, data, bytes); 165 ndata[bytes] = '\0'; 166 } 167 else 168 bytes = 0; 169 raw->data = (void *) ndata; 170 raw->bytes = bytes; 171} 172 173static value_t * 174value_copy(const void *item) 175{ 176 value_t *ret = stp_malloc(sizeof(value_t)); 177 const value_t *v = (const value_t *) (item); 178 ret->name = stp_strdup(v->name); 179 ret->typ = v->typ; 180 ret->active = v->active; 181 switch (v->typ) 182 { 183 case STP_PARAMETER_TYPE_CURVE: 184 ret->value.cval = stp_curve_create_copy(v->value.cval); 185 break; 186 case STP_PARAMETER_TYPE_ARRAY: 187 ret->value.aval = stp_array_create_copy(v->value.aval); 188 break; 189 case STP_PARAMETER_TYPE_STRING_LIST: 190 case STP_PARAMETER_TYPE_FILE: 191 case STP_PARAMETER_TYPE_RAW: 192 copy_to_raw(&(ret->value.rval), v->value.rval.data, v->value.rval.bytes); 193 break; 194 case STP_PARAMETER_TYPE_INT: 195 case STP_PARAMETER_TYPE_DIMENSION: 196 case STP_PARAMETER_TYPE_BOOLEAN: 197 ret->value.ival = v->value.ival; 198 break; 199 case STP_PARAMETER_TYPE_DOUBLE: 200 ret->value.dval = v->value.dval; 201 break; 202 default: 203 break; 204 } 205 return ret; 206} 207 208static stp_list_t * 209copy_value_list(const stp_list_t *src) 210{ 211 stp_list_t *ret = create_vars_list(); 212 const stp_list_item_t *item = stp_list_get_start((const stp_list_t *)src); 213 while (item) 214 { 215 stp_list_item_create(ret, NULL, value_copy(stp_list_item_get_data(item))); 216 item = stp_list_item_next(item); 217 } 218 return ret; 219} 220 221static const char * 222compdata_namefunc(const void *item) 223{ 224 const compdata_t *cd = (const compdata_t *) (item); 225 return cd->name; 226} 227 228static void 229compdata_freefunc(void *item) 230{ 231 compdata_t *cd = (compdata_t *) (item); 232 if (cd->freefunc) 233 (cd->freefunc)(cd->data); 234 stp_free(cd->name); 235 stp_free(cd); 236} 237 238static void * 239compdata_copyfunc(const void *item) 240{ 241 const compdata_t *cd = (const compdata_t *) (item); 242 if (cd->copyfunc) 243 return (cd->copyfunc)(cd->data); 244 else 245 return cd->data; 246} 247 248void 249stp_allocate_component_data(stp_vars_t *v, 250 const char *name, 251 stp_copy_data_func_t copyfunc, 252 stp_free_data_func_t freefunc, 253 void *data) 254{ 255 compdata_t *cd; 256 stp_list_item_t *item; 257 CHECK_VARS(v); 258 cd = stp_malloc(sizeof(compdata_t)); 259 item = stp_list_get_item_by_name(v->internal_data, name); 260 if (item) 261 stp_list_item_destroy(v->internal_data, item); 262 cd->name = stp_strdup(name); 263 cd->copyfunc = copyfunc; 264 cd->freefunc = freefunc; 265 cd->data = data; 266 stp_list_item_create(v->internal_data, NULL, cd); 267} 268 269void 270stp_destroy_component_data(stp_vars_t *v, const char *name) 271{ 272 stp_list_item_t *item; 273 CHECK_VARS(v); 274 item = stp_list_get_item_by_name(v->internal_data, name); 275 if (item) 276 stp_list_item_destroy(v->internal_data, item); 277} 278 279void * 280stp_get_component_data(const stp_vars_t *v, const char *name) 281{ 282 stp_list_item_t *item; 283 CHECK_VARS(v); 284 item = stp_list_get_item_by_name(v->internal_data, name); 285 if (item) 286 return ((compdata_t *) stp_list_item_get_data(item))->data; 287 else 288 return NULL; 289} 290 291static stp_list_t * 292create_compdata_list(void) 293{ 294 stp_list_t *ret = stp_list_create(); 295 stp_list_set_freefunc(ret, compdata_freefunc); 296 stp_list_set_namefunc(ret, compdata_namefunc); 297 return ret; 298} 299 300static stp_list_t * 301copy_compdata_list(const stp_list_t *src) 302{ 303 stp_list_t *ret = create_compdata_list(); 304 const stp_list_item_t *item = stp_list_get_start(src); 305 while (item) 306 { 307 stp_list_item_create(ret, NULL, compdata_copyfunc(item)); 308 item = stp_list_item_next(item); 309 } 310 return ret; 311} 312 313static void 314initialize_standard_vars(void) 315{ 316 if (!standard_vars_initialized) 317 { 318 int i; 319 for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++) 320 default_vars.params[i] = create_vars_list(); 321 default_vars.driver = stp_strdup("ps2"); 322 default_vars.color_conversion = stp_strdup("traditional"); 323 default_vars.internal_data = create_compdata_list(); 324 standard_vars_initialized = 1; 325 } 326} 327 328const stp_vars_t * 329stp_default_settings(void) 330{ 331 initialize_standard_vars(); 332 return (stp_vars_t *) &default_vars; 333} 334 335stp_vars_t * 336stp_vars_create(void) 337{ 338 int i; 339 stp_vars_t *retval = stp_zalloc(sizeof(stp_vars_t)); 340 initialize_standard_vars(); 341 for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++) 342 retval->params[i] = create_vars_list(); 343 retval->internal_data = create_compdata_list(); 344 stp_vars_copy(retval, (stp_vars_t *)&default_vars); 345 return (retval); 346} 347 348void 349stp_vars_destroy(stp_vars_t *v) 350{ 351 int i; 352 CHECK_VARS(v); 353 for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++) 354 stp_list_destroy(v->params[i]); 355 stp_list_destroy(v->internal_data); 356 STP_SAFE_FREE(v->driver); 357 STP_SAFE_FREE(v->color_conversion); 358 stp_free(v); 359} 360 361#define DEF_STRING_FUNCS(s, pre) \ 362void \ 363pre##_set_##s(stp_vars_t *v, const char *val) \ 364{ \ 365 CHECK_VARS(v); \ 366 if (val) \ 367 stp_deprintf(STP_DBG_VARS, "set %s to %s (0x%p)\n", #s, val, \ 368 (const void *) v); \ 369 else \ 370 stp_deprintf(STP_DBG_VARS, "clear %s (0x%p)\n", #s, \ 371 (const void *) v); \ 372 if (v->s == val) \ 373 return; \ 374 STP_SAFE_FREE(v->s); \ 375 v->s = stp_strdup(val); \ 376 v->verified = 0; \ 377} \ 378 \ 379void \ 380pre##_set_##s##_n(stp_vars_t *v, const char *val, int n) \ 381{ \ 382 CHECK_VARS(v); \ 383 if (v->s == val) \ 384 return; \ 385 STP_SAFE_FREE(v->s); \ 386 v->s = stp_strndup(val, n); \ 387 v->verified = 0; \ 388} \ 389 \ 390const char * \ 391pre##_get_##s(const stp_vars_t *v) \ 392{ \ 393 CHECK_VARS(v); \ 394 return v->s; \ 395} 396 397#define DEF_FUNCS(s, t, pre) \ 398void \ 399pre##_set_##s(stp_vars_t *v, t val) \ 400{ \ 401 CHECK_VARS(v); \ 402 v->verified = 0; \ 403 v->s = val; \ 404} \ 405 \ 406t \ 407pre##_get_##s(const stp_vars_t *v) \ 408{ \ 409 CHECK_VARS(v); \ 410 return v->s; \ 411} 412 413DEF_STRING_FUNCS(driver, stp) 414DEF_STRING_FUNCS(color_conversion, stp) 415DEF_FUNCS(left, int, stp) 416DEF_FUNCS(top, int, stp) 417DEF_FUNCS(width, int, stp) 418DEF_FUNCS(height, int, stp) 419DEF_FUNCS(page_width, int, stp) 420DEF_FUNCS(page_height, int, stp) 421DEF_FUNCS(outdata, void *, stp) 422DEF_FUNCS(errdata, void *, stp) 423DEF_FUNCS(outfunc, stp_outfunc_t, stp) 424DEF_FUNCS(errfunc, stp_outfunc_t, stp) 425 426void 427stp_set_verified(stp_vars_t *v, int val) 428{ 429 CHECK_VARS(v); 430 v->verified = val; 431} 432 433int 434stp_get_verified(const stp_vars_t *v) 435{ 436 CHECK_VARS(v); 437 return v->verified; 438} 439 440static void 441set_default_raw_parameter(stp_list_t *list, const char *parameter, 442 const char *value, size_t bytes, int typ) 443{ 444 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 445 if (value && !item) 446 { 447 value_t *val = stp_malloc(sizeof(value_t)); 448 val->name = stp_strdup(parameter); 449 val->typ = typ; 450 val->active = STP_PARAMETER_DEFAULTED; 451 stp_list_item_create(list, NULL, val); 452 copy_to_raw(&(val->value.rval), value, bytes); 453 } 454} 455 456static void 457set_raw_parameter(stp_list_t *list, const char *parameter, const char *value, 458 size_t bytes, int typ) 459{ 460 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 461 if (value) 462 { 463 value_t *val; 464 if (item) 465 { 466 val = (value_t *) stp_list_item_get_data(item); 467 if (val->active == STP_PARAMETER_DEFAULTED) 468 val->active = STP_PARAMETER_ACTIVE; 469 stp_free((void *) val->value.rval.data); 470 } 471 else 472 { 473 val = stp_malloc(sizeof(value_t)); 474 val->name = stp_strdup(parameter); 475 val->typ = typ; 476 val->active = STP_PARAMETER_ACTIVE; 477 stp_list_item_create(list, NULL, val); 478 } 479 copy_to_raw(&(val->value.rval), value, bytes); 480 } 481 else if (item) 482 stp_list_item_destroy(list, item); 483} 484 485void 486stp_set_string_parameter_n(stp_vars_t *v, const char *parameter, 487 const char *value, size_t bytes) 488{ 489 stp_list_t *list = v->params[STP_PARAMETER_TYPE_STRING_LIST]; 490 if (value) 491 stp_deprintf(STP_DBG_VARS, "stp_set_string_parameter(0x%p, %s, %s)\n", 492 (const void *) v, parameter, value); 493 else 494 stp_deprintf(STP_DBG_VARS, "stp_set_string_parameter(0x%p, %s)\n", 495 (const void *) v, parameter); 496 set_raw_parameter(list, parameter, value, bytes, 497 STP_PARAMETER_TYPE_STRING_LIST); 498 stp_set_verified(v, 0); 499} 500 501void 502stp_set_string_parameter(stp_vars_t *v, const char *parameter, 503 const char *value) 504{ 505 int byte_count = 0; 506 if (value) 507 byte_count = strlen(value); 508 stp_deprintf(STP_DBG_VARS, "stp_set_string_parameter(0x%p, %s, %s)\n", 509 (const void *) v, parameter, value ? value : "NULL"); 510 stp_set_string_parameter_n(v, parameter, value, byte_count); 511 stp_set_verified(v, 0); 512} 513 514void 515stp_set_default_string_parameter_n(stp_vars_t *v, const char *parameter, 516 const char *value, size_t bytes) 517{ 518 stp_list_t *list = v->params[STP_PARAMETER_TYPE_STRING_LIST]; 519 stp_deprintf(STP_DBG_VARS, "stp_set_default_string_parameter(0x%p, %s, %s)\n", 520 (const void *) v, parameter, value ? value : "NULL"); 521 set_default_raw_parameter(list, parameter, value, bytes, 522 STP_PARAMETER_TYPE_STRING_LIST); 523 stp_set_verified(v, 0); 524} 525 526void 527stp_set_default_string_parameter(stp_vars_t *v, const char *parameter, 528 const char *value) 529{ 530 int byte_count = 0; 531 if (value) 532 byte_count = strlen(value); 533 stp_set_default_string_parameter_n(v, parameter, value, byte_count); 534 stp_set_verified(v, 0); 535} 536 537void 538stp_clear_string_parameter(stp_vars_t *v, const char *parameter) 539{ 540 stp_set_string_parameter(v, parameter, NULL); 541} 542 543const char * 544stp_get_string_parameter(const stp_vars_t *v, const char *parameter) 545{ 546 stp_list_t *list = v->params[STP_PARAMETER_TYPE_STRING_LIST]; 547 value_t *val; 548 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 549 if (item) 550 { 551 val = (value_t *) stp_list_item_get_data(item); 552 return val->value.rval.data; 553 } 554 else 555 return NULL; 556} 557 558void 559stp_set_raw_parameter(stp_vars_t *v, const char *parameter, 560 const void *value, size_t bytes) 561{ 562 stp_list_t *list = v->params[STP_PARAMETER_TYPE_RAW]; 563 set_raw_parameter(list, parameter, value, bytes, STP_PARAMETER_TYPE_RAW); 564 stp_set_verified(v, 0); 565} 566 567void 568stp_set_default_raw_parameter(stp_vars_t *v, const char *parameter, 569 const void *value, size_t bytes) 570{ 571 stp_list_t *list = v->params[STP_PARAMETER_TYPE_RAW]; 572 set_default_raw_parameter(list, parameter, value, bytes, 573 STP_PARAMETER_TYPE_RAW); 574 stp_set_verified(v, 0); 575} 576 577void 578stp_clear_raw_parameter(stp_vars_t *v, const char *parameter) 579{ 580 stp_set_raw_parameter(v, parameter, NULL, 0); 581} 582 583const stp_raw_t * 584stp_get_raw_parameter(const stp_vars_t *v, const char *parameter) 585{ 586 const stp_list_t *list = v->params[STP_PARAMETER_TYPE_RAW]; 587 const value_t *val; 588 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 589 if (item) 590 { 591 val = (const value_t *) stp_list_item_get_data(item); 592 return &(val->value.rval); 593 } 594 else 595 return NULL; 596} 597 598void 599stp_set_file_parameter(stp_vars_t *v, const char *parameter, 600 const char *value) 601{ 602 stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE]; 603 size_t byte_count = 0; 604 if (value) 605 byte_count = strlen(value); 606 stp_deprintf(STP_DBG_VARS, "stp_set_file_parameter(0x%p, %s, %s)\n", 607 (const void *) v, parameter, value ? value : "NULL"); 608 set_raw_parameter(list, parameter, value, byte_count, 609 STP_PARAMETER_TYPE_FILE); 610 stp_set_verified(v, 0); 611} 612 613void 614stp_set_file_parameter_n(stp_vars_t *v, const char *parameter, 615 const char *value, size_t byte_count) 616{ 617 stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE]; 618 stp_deprintf(STP_DBG_VARS, "stp_set_file_parameter(0x%p, %s, %s)\n", 619 (const void *) v, parameter, value ? value : "NULL"); 620 set_raw_parameter(list, parameter, value, byte_count, 621 STP_PARAMETER_TYPE_FILE); 622 stp_set_verified(v, 0); 623} 624 625void 626stp_set_default_file_parameter(stp_vars_t *v, const char *parameter, 627 const char *value) 628{ 629 stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE]; 630 size_t byte_count = 0; 631 if (value) 632 byte_count = strlen(value); 633 stp_deprintf(STP_DBG_VARS, "stp_set_default_file_parameter(0x%p, %s, %s)\n", 634 (const void *) v, parameter, value ? value : "NULL"); 635 set_default_raw_parameter(list, parameter, value, byte_count, 636 STP_PARAMETER_TYPE_FILE); 637 stp_set_verified(v, 0); 638} 639 640void 641stp_set_default_file_parameter_n(stp_vars_t *v, const char *parameter, 642 const char *value, size_t byte_count) 643{ 644 stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE]; 645 stp_deprintf(STP_DBG_VARS, "stp_set_default_file_parameter(0x%p, %s, %s)\n", 646 (const void *) v, parameter, value ? value : "NULL"); 647 set_default_raw_parameter(list, parameter, value, byte_count, 648 STP_PARAMETER_TYPE_FILE); 649 stp_set_verified(v, 0); 650} 651 652void 653stp_clear_file_parameter(stp_vars_t *v, const char *parameter) 654{ 655 stp_set_file_parameter(v, parameter, NULL); 656} 657 658const char * 659stp_get_file_parameter(const stp_vars_t *v, const char *parameter) 660{ 661 const stp_list_t *list = v->params[STP_PARAMETER_TYPE_FILE]; 662 const value_t *val; 663 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 664 if (item) 665 { 666 val = (const value_t *) stp_list_item_get_data(item); 667 return val->value.rval.data; 668 } 669 else 670 return NULL; 671} 672 673void 674stp_set_curve_parameter(stp_vars_t *v, const char *parameter, 675 const stp_curve_t *curve) 676{ 677 stp_list_t *list = v->params[STP_PARAMETER_TYPE_CURVE]; 678 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 679 stp_deprintf(STP_DBG_VARS, "stp_set_curve_parameter(0x%p, %s)\n", 680 (const void *) v, parameter); 681 if (curve) 682 { 683 value_t *val; 684 if (item) 685 { 686 val = (value_t *) stp_list_item_get_data(item); 687 if (val->active == STP_PARAMETER_DEFAULTED) 688 val->active = STP_PARAMETER_ACTIVE; 689 if (val->value.cval) 690 stp_curve_destroy(val->value.cval); 691 } 692 else 693 { 694 val = stp_malloc(sizeof(value_t)); 695 val->name = stp_strdup(parameter); 696 val->typ = STP_PARAMETER_TYPE_CURVE; 697 val->active = STP_PARAMETER_ACTIVE; 698 stp_list_item_create(list, NULL, val); 699 } 700 val->value.cval = stp_curve_create_copy(curve); 701 } 702 else if (item) 703 stp_list_item_destroy(list, item); 704 stp_set_verified(v, 0); 705} 706 707void 708stp_set_default_curve_parameter(stp_vars_t *v, const char *parameter, 709 const stp_curve_t *curve) 710{ 711 stp_list_t *list = v->params[STP_PARAMETER_TYPE_CURVE]; 712 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 713 stp_deprintf(STP_DBG_VARS, "stp_set_default_curve_parameter(0x%p, %s)\n", 714 (const void *) v, parameter); 715 if (!item) 716 { 717 if (curve) 718 { 719 value_t *val; 720 val = stp_malloc(sizeof(value_t)); 721 val->name = stp_strdup(parameter); 722 val->typ = STP_PARAMETER_TYPE_CURVE; 723 val->active = STP_PARAMETER_DEFAULTED; 724 stp_list_item_create(list, NULL, val); 725 val->value.cval = stp_curve_create_copy(curve); 726 } 727 } 728 stp_set_verified(v, 0); 729} 730 731void 732stp_clear_curve_parameter(stp_vars_t *v, const char *parameter) 733{ 734 stp_set_curve_parameter(v, parameter, NULL); 735} 736 737const stp_curve_t * 738stp_get_curve_parameter(const stp_vars_t *v, const char *parameter) 739{ 740 const stp_list_t *list = v->params[STP_PARAMETER_TYPE_CURVE]; 741 const value_t *val; 742 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 743 if (item) 744 { 745 val = (value_t *) stp_list_item_get_data(item); 746 return val->value.cval; 747 } 748 else 749 return NULL; 750} 751 752void 753stp_set_array_parameter(stp_vars_t *v, const char *parameter, 754 const stp_array_t *array) 755{ 756 stp_list_t *list = v->params[STP_PARAMETER_TYPE_ARRAY]; 757 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 758 stp_deprintf(STP_DBG_VARS, "stp_set_array_parameter(0x%p, %s)\n", 759 (const void *) v, parameter); 760 if (array) 761 { 762 value_t *val; 763 if (item) 764 { 765 val = (value_t *) stp_list_item_get_data(item); 766 if (val->active == STP_PARAMETER_DEFAULTED) 767 val->active = STP_PARAMETER_ACTIVE; 768 stp_array_destroy(val->value.aval); 769 } 770 else 771 { 772 val = stp_malloc(sizeof(value_t)); 773 val->name = stp_strdup(parameter); 774 val->typ = STP_PARAMETER_TYPE_ARRAY; 775 val->active = STP_PARAMETER_ACTIVE; 776 stp_list_item_create(list, NULL, val); 777 } 778 val->value.aval = stp_array_create_copy(array); 779 } 780 else if (item) 781 stp_list_item_destroy(list, item); 782 stp_set_verified(v, 0); 783} 784 785void 786stp_set_default_array_parameter(stp_vars_t *v, const char *parameter, 787 const stp_array_t *array) 788{ 789 stp_list_t *list = v->params[STP_PARAMETER_TYPE_ARRAY]; 790 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 791 stp_deprintf(STP_DBG_VARS, "stp_set_default_array_parameter(0x%p, %s)\n", 792 (const void *) v, parameter); 793 if (!item) 794 { 795 if (array) 796 { 797 value_t *val; 798 val = stp_malloc(sizeof(value_t)); 799 val->name = stp_strdup(parameter); 800 val->typ = STP_PARAMETER_TYPE_ARRAY; 801 val->active = STP_PARAMETER_DEFAULTED; 802 stp_list_item_create(list, NULL, val); 803 val->value.aval = stp_array_create_copy(array); 804 } 805 } 806 stp_set_verified(v, 0); 807} 808 809void 810stp_clear_array_parameter(stp_vars_t *v, const char *parameter) 811{ 812 stp_set_array_parameter(v, parameter, NULL); 813} 814 815const stp_array_t * 816stp_get_array_parameter(const stp_vars_t *v, const char *parameter) 817{ 818 const stp_list_t *list = v->params[STP_PARAMETER_TYPE_ARRAY]; 819 const value_t *val; 820 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 821 if (item) 822 { 823 val = (const value_t *) stp_list_item_get_data(item); 824 return val->value.aval; 825 } 826 else 827 return NULL; 828} 829 830void 831stp_set_int_parameter(stp_vars_t *v, const char *parameter, int ival) 832{ 833 stp_list_t *list = v->params[STP_PARAMETER_TYPE_INT]; 834 value_t *val; 835 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 836 stp_deprintf(STP_DBG_VARS, "stp_set_int_parameter(0x%p, %s, %d)\n", 837 (const void *) v, parameter, ival); 838 if (item) 839 { 840 val = (value_t *) stp_list_item_get_data(item); 841 if (val->active == STP_PARAMETER_DEFAULTED) 842 val->active = STP_PARAMETER_ACTIVE; 843 } 844 else 845 { 846 val = stp_malloc(sizeof(value_t)); 847 val->name = stp_strdup(parameter); 848 val->typ = STP_PARAMETER_TYPE_INT; 849 val->active = STP_PARAMETER_ACTIVE; 850 stp_list_item_create(list, NULL, val); 851 } 852 val->value.ival = ival; 853 stp_set_verified(v, 0); 854} 855 856void 857stp_set_default_int_parameter(stp_vars_t *v, const char *parameter, int ival) 858{ 859 stp_list_t *list = v->params[STP_PARAMETER_TYPE_INT]; 860 value_t *val; 861 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 862 stp_deprintf(STP_DBG_VARS, "stp_set_default_int_parameter(0x%p, %s, %d)\n", 863 (const void *) v, parameter, ival); 864 if (!item) 865 { 866 val = stp_malloc(sizeof(value_t)); 867 val->name = stp_strdup(parameter); 868 val->typ = STP_PARAMETER_TYPE_INT; 869 val->active = STP_PARAMETER_DEFAULTED; 870 stp_list_item_create(list, NULL, val); 871 val->value.ival = ival; 872 } 873 stp_set_verified(v, 0); 874} 875 876void 877stp_clear_int_parameter(stp_vars_t *v, const char *parameter) 878{ 879 stp_list_t *list = v->params[STP_PARAMETER_TYPE_INT]; 880 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 881 stp_deprintf(STP_DBG_VARS, "stp_clear_int_parameter(0x%p, %s)\n", 882 (const void *) v, parameter); 883 if (item) 884 stp_list_item_destroy(list, item); 885 stp_set_verified(v, 0); 886} 887 888int 889stp_get_int_parameter(const stp_vars_t *v, const char *parameter) 890{ 891 const stp_list_t *list = v->params[STP_PARAMETER_TYPE_INT]; 892 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 893 if (item) 894 { 895 const value_t *val = (const value_t *) stp_list_item_get_data(item); 896 return val->value.ival; 897 } 898 else 899 { 900 stp_parameter_t desc; 901 stp_describe_parameter(v, parameter, &desc); 902 if (desc.p_type == STP_PARAMETER_TYPE_INT) 903 { 904 int intval = desc.deflt.integer; 905 stp_parameter_description_destroy(&desc); 906 return intval; 907 } 908 else 909 { 910 stp_parameter_description_destroy(&desc); 911 stp_erprintf 912 ("Gutenprint: Attempt to retrieve unset integer parameter %s\n", 913 parameter); 914 return 0; 915 } 916 } 917} 918 919void 920stp_set_boolean_parameter(stp_vars_t *v, const char *parameter, int ival) 921{ 922 stp_list_t *list = v->params[STP_PARAMETER_TYPE_BOOLEAN]; 923 value_t *val; 924 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 925 stp_deprintf(STP_DBG_VARS, "stp_set_boolean_parameter(0x%p, %s, %d)\n", 926 (const void *) v, parameter, ival); 927 if (item) 928 { 929 val = (value_t *) stp_list_item_get_data(item); 930 if (val->active == STP_PARAMETER_DEFAULTED) 931 val->active = STP_PARAMETER_ACTIVE; 932 } 933 else 934 { 935 val = stp_malloc(sizeof(value_t)); 936 val->name = stp_strdup(parameter); 937 val->typ = STP_PARAMETER_TYPE_BOOLEAN; 938 val->active = STP_PARAMETER_ACTIVE; 939 stp_list_item_create(list, NULL, val); 940 } 941 if (ival) 942 val->value.ival = 1; 943 else 944 val->value.ival = 0; 945 stp_set_verified(v, 0); 946} 947 948void 949stp_set_default_boolean_parameter(stp_vars_t *v, const char *parameter, 950 int ival) 951{ 952 stp_list_t *list = v->params[STP_PARAMETER_TYPE_BOOLEAN]; 953 value_t *val; 954 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 955 stp_deprintf(STP_DBG_VARS, "stp_set_default_boolean_parameter(0x%p, %s, %d)\n", 956 (const void *) v, parameter, ival); 957 if (!item) 958 { 959 val = stp_malloc(sizeof(value_t)); 960 val->name = stp_strdup(parameter); 961 val->typ = STP_PARAMETER_TYPE_BOOLEAN; 962 val->active = STP_PARAMETER_DEFAULTED; 963 stp_list_item_create(list, NULL, val); 964 if (ival) 965 val->value.ival = 1; 966 else 967 val->value.ival = 0; 968 } 969 stp_set_verified(v, 0); 970} 971 972void 973stp_clear_boolean_parameter(stp_vars_t *v, const char *parameter) 974{ 975 stp_list_t *list = v->params[STP_PARAMETER_TYPE_BOOLEAN]; 976 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 977 stp_deprintf(STP_DBG_VARS, "stp_clear_boolean_parameter(0x%p, %s)\n", 978 (const void *) v, parameter); 979 if (item) 980 stp_list_item_destroy(list, item); 981 stp_set_verified(v, 0); 982} 983 984int 985stp_get_boolean_parameter(const stp_vars_t *v, const char *parameter) 986{ 987 const stp_list_t *list = v->params[STP_PARAMETER_TYPE_BOOLEAN]; 988 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 989 if (item) 990 { 991 const value_t *val = (const value_t *) stp_list_item_get_data(item); 992 return val->value.ival; 993 } 994 else 995 { 996 stp_parameter_t desc; 997 stp_describe_parameter(v, parameter, &desc); 998 if (desc.p_type == STP_PARAMETER_TYPE_BOOLEAN) 999 { 1000 int boolean = desc.deflt.boolean; 1001 stp_parameter_description_destroy(&desc); 1002 return boolean; 1003 } 1004 else 1005 { 1006 stp_parameter_description_destroy(&desc); 1007 stp_erprintf 1008 ("Gutenprint: Attempt to retrieve unset boolean parameter %s\n", 1009 parameter); 1010 return 0; 1011 } 1012 } 1013} 1014 1015void 1016stp_set_dimension_parameter(stp_vars_t *v, const char *parameter, int ival) 1017{ 1018 stp_list_t *list = v->params[STP_PARAMETER_TYPE_DIMENSION]; 1019 value_t *val; 1020 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1021 stp_deprintf(STP_DBG_VARS, "stp_set_dimension_parameter(0x%p, %s, %d)\n", 1022 (const void *) v, parameter, ival); 1023 if (item) 1024 { 1025 val = (value_t *) stp_list_item_get_data(item); 1026 if (val->active == STP_PARAMETER_DEFAULTED) 1027 val->active = STP_PARAMETER_ACTIVE; 1028 } 1029 else 1030 { 1031 val = stp_malloc(sizeof(value_t)); 1032 val->name = stp_strdup(parameter); 1033 val->typ = STP_PARAMETER_TYPE_DIMENSION; 1034 val->active = STP_PARAMETER_ACTIVE; 1035 stp_list_item_create(list, NULL, val); 1036 } 1037 val->value.ival = ival; 1038 stp_set_verified(v, 0); 1039} 1040 1041void 1042stp_set_default_dimension_parameter(stp_vars_t *v, const char *parameter, int ival) 1043{ 1044 stp_list_t *list = v->params[STP_PARAMETER_TYPE_DIMENSION]; 1045 value_t *val; 1046 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1047 stp_deprintf(STP_DBG_VARS, "stp_set_default_dimension_parameter(0x%p, %s, %d)\n", 1048 (const void *) v, parameter, ival); 1049 if (!item) 1050 { 1051 val = stp_malloc(sizeof(value_t)); 1052 val->name = stp_strdup(parameter); 1053 val->typ = STP_PARAMETER_TYPE_DIMENSION; 1054 val->active = STP_PARAMETER_DEFAULTED; 1055 stp_list_item_create(list, NULL, val); 1056 val->value.ival = ival; 1057 } 1058 stp_set_verified(v, 0); 1059} 1060 1061void 1062stp_clear_dimension_parameter(stp_vars_t *v, const char *parameter) 1063{ 1064 stp_list_t *list = v->params[STP_PARAMETER_TYPE_DIMENSION]; 1065 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1066 stp_deprintf(STP_DBG_VARS, "stp_clear_dimension_parameter(0x%p, %s)\n", 1067 (const void *) v, parameter); 1068 if (item) 1069 stp_list_item_destroy(list, item); 1070 stp_set_verified(v, 0); 1071} 1072 1073int 1074stp_get_dimension_parameter(const stp_vars_t *v, const char *parameter) 1075{ 1076 const stp_list_t *list = v->params[STP_PARAMETER_TYPE_DIMENSION]; 1077 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1078 if (item) 1079 { 1080 const value_t *val = (const value_t *) stp_list_item_get_data(item); 1081 return val->value.ival; 1082 } 1083 else 1084 { 1085 stp_parameter_t desc; 1086 stp_describe_parameter(v, parameter, &desc); 1087 if (desc.p_type == STP_PARAMETER_TYPE_DIMENSION) 1088 { 1089 int intval = desc.deflt.integer; 1090 stp_parameter_description_destroy(&desc); 1091 return intval; 1092 } 1093 else 1094 { 1095 stp_parameter_description_destroy(&desc); 1096 stp_erprintf 1097 ("Gutenprint: Attempt to retrieve unset dimension parameter %s\n", 1098 parameter); 1099 return 0; 1100 } 1101 } 1102} 1103 1104void 1105stp_set_float_parameter(stp_vars_t *v, const char *parameter, double dval) 1106{ 1107 stp_list_t *list = v->params[STP_PARAMETER_TYPE_DOUBLE]; 1108 value_t *val; 1109 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1110 stp_deprintf(STP_DBG_VARS, "stp_set_float_parameter(0x%p, %s, %f)\n", 1111 (const void *) v, parameter, dval); 1112 if (item) 1113 { 1114 val = (value_t *) stp_list_item_get_data(item); 1115 if (val->active == STP_PARAMETER_DEFAULTED) 1116 val->active = STP_PARAMETER_ACTIVE; 1117 } 1118 else 1119 { 1120 val = stp_malloc(sizeof(value_t)); 1121 val->name = stp_strdup(parameter); 1122 val->typ = STP_PARAMETER_TYPE_DOUBLE; 1123 val->active = STP_PARAMETER_ACTIVE; 1124 stp_list_item_create(list, NULL, val); 1125 } 1126 val->value.dval = dval; 1127 stp_set_verified(v, 0); 1128} 1129 1130void 1131stp_set_default_float_parameter(stp_vars_t *v, const char *parameter, 1132 double dval) 1133{ 1134 stp_list_t *list = v->params[STP_PARAMETER_TYPE_DOUBLE]; 1135 value_t *val; 1136 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1137 stp_deprintf(STP_DBG_VARS, "stp_set_default_float_parameter(0x%p, %s, %f)\n", 1138 (const void *) v, parameter, dval); 1139 if (!item) 1140 { 1141 val = stp_malloc(sizeof(value_t)); 1142 val->name = stp_strdup(parameter); 1143 val->typ = STP_PARAMETER_TYPE_DOUBLE; 1144 val->active = STP_PARAMETER_DEFAULTED; 1145 stp_list_item_create(list, NULL, val); 1146 val->value.dval = dval; 1147 } 1148 stp_set_verified(v, 0); 1149} 1150 1151void 1152stp_clear_float_parameter(stp_vars_t *v, const char *parameter) 1153{ 1154 stp_list_t *list = v->params[STP_PARAMETER_TYPE_DOUBLE]; 1155 stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1156 stp_deprintf(STP_DBG_VARS, "stp_clear_float_parameter(0x%p, %s)\n", 1157 (const void *) v, parameter); 1158 if (item) 1159 stp_list_item_destroy(list, item); 1160 stp_set_verified(v, 0); 1161} 1162 1163double 1164stp_get_float_parameter(const stp_vars_t *v, const char *parameter) 1165{ 1166 const stp_list_t *list = v->params[STP_PARAMETER_TYPE_DOUBLE]; 1167 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1168 if (item) 1169 { 1170 const value_t *val = (value_t *) stp_list_item_get_data(item); 1171 return val->value.dval; 1172 } 1173 else 1174 { 1175 stp_parameter_t desc; 1176 stp_describe_parameter(v, parameter, &desc); 1177 if (desc.p_type == STP_PARAMETER_TYPE_DOUBLE) 1178 { 1179 double dbl = desc.deflt.dbl; 1180 stp_parameter_description_destroy(&desc); 1181 return dbl; 1182 } 1183 else 1184 { 1185 stp_parameter_description_destroy(&desc); 1186 stp_erprintf 1187 ("Gutenprint: Attempt to retrieve unset float parameter %s\n", 1188 parameter); 1189 return 1.0; 1190 } 1191 } 1192} 1193 1194void 1195stp_scale_float_parameter(stp_vars_t *v, const char *parameter, 1196 double scale) 1197{ 1198 double val; 1199 if (stp_check_float_parameter(v, parameter, STP_PARAMETER_DEFAULTED)) 1200 val = stp_get_float_parameter(v, parameter); 1201 else 1202 { 1203 stp_parameter_t desc; 1204 stp_describe_parameter(v, parameter, &desc); 1205 if (desc.p_type != STP_PARAMETER_TYPE_DOUBLE) 1206 { 1207 stp_parameter_description_destroy(&desc); 1208 return; 1209 } 1210 val = desc.deflt.dbl; 1211 stp_parameter_description_destroy(&desc); 1212 } 1213 stp_deprintf(STP_DBG_VARS, "stp_scale_float_parameter(%p, %s, %f*%f)\n", 1214 (const void *) v, parameter, val, scale); 1215 stp_set_float_parameter(v, parameter, val * scale); 1216} 1217 1218void 1219stp_clear_parameter(stp_vars_t *v, const char *parameter, stp_parameter_type_t type) 1220{ 1221 switch (type) 1222 { 1223 case STP_PARAMETER_TYPE_STRING_LIST: 1224 stp_clear_string_parameter(v, parameter); 1225 break; 1226 case STP_PARAMETER_TYPE_FILE: 1227 stp_clear_file_parameter(v, parameter); 1228 break; 1229 case STP_PARAMETER_TYPE_DOUBLE: 1230 stp_clear_float_parameter(v, parameter); 1231 break; 1232 case STP_PARAMETER_TYPE_INT: 1233 stp_clear_int_parameter(v, parameter); 1234 break; 1235 case STP_PARAMETER_TYPE_DIMENSION: 1236 stp_clear_dimension_parameter(v, parameter); 1237 break; 1238 case STP_PARAMETER_TYPE_BOOLEAN: 1239 stp_clear_boolean_parameter(v, parameter); 1240 break; 1241 case STP_PARAMETER_TYPE_CURVE: 1242 stp_clear_curve_parameter(v, parameter); 1243 break; 1244 case STP_PARAMETER_TYPE_ARRAY: 1245 stp_clear_array_parameter(v, parameter); 1246 break; 1247 case STP_PARAMETER_TYPE_RAW: 1248 stp_clear_raw_parameter(v, parameter); 1249 break; 1250 default: 1251 stp_eprintf(v, "Attempt to clear unknown type parameter!\n"); 1252 } 1253} 1254 1255 1256int 1257stp_check_parameter(const stp_vars_t *v, 1258 const char *parameter, 1259 stp_parameter_activity_t active, 1260 stp_parameter_type_t p_type) 1261{ 1262 if (p_type >= STP_PARAMETER_TYPE_STRING_LIST && 1263 p_type < STP_PARAMETER_TYPE_INVALID) 1264 { 1265 const stp_list_t *list = v->params[p_type]; 1266 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1267 if (item && 1268 active <= ((const value_t *) stp_list_item_get_data(item))->active) 1269 return 1; 1270 else 1271 return 0; 1272 } 1273 return 0; 1274} 1275 1276#define CHECK_FUNCTION(type, index) \ 1277int \ 1278stp_check_##type##_parameter(const stp_vars_t *v, const char *parameter, \ 1279 stp_parameter_activity_t active) \ 1280{ \ 1281 return stp_check_parameter(v, parameter, active, index); \ 1282} 1283 1284CHECK_FUNCTION(string, STP_PARAMETER_TYPE_STRING_LIST) 1285CHECK_FUNCTION(file, STP_PARAMETER_TYPE_FILE) 1286CHECK_FUNCTION(float, STP_PARAMETER_TYPE_DOUBLE) 1287CHECK_FUNCTION(int, STP_PARAMETER_TYPE_INT) 1288CHECK_FUNCTION(dimension, STP_PARAMETER_TYPE_DIMENSION) 1289CHECK_FUNCTION(boolean, STP_PARAMETER_TYPE_BOOLEAN) 1290CHECK_FUNCTION(curve, STP_PARAMETER_TYPE_CURVE) 1291CHECK_FUNCTION(array, STP_PARAMETER_TYPE_ARRAY) 1292CHECK_FUNCTION(raw, STP_PARAMETER_TYPE_RAW) 1293 1294stp_string_list_t * 1295stp_list_parameters(const stp_vars_t *v, stp_parameter_type_t p_type) 1296{ 1297 if (p_type >= STP_PARAMETER_TYPE_STRING_LIST && 1298 p_type < STP_PARAMETER_TYPE_INVALID) 1299 { 1300 const stp_list_t *list = v->params[p_type]; 1301 stp_string_list_t *answer = stp_string_list_create(); 1302 const stp_list_item_t *li = stp_list_get_start(list); 1303 while (li) 1304 { 1305 const value_t *val = (value_t *) stp_list_item_get_data(li); 1306 stp_string_list_add_string(answer, val->name, val->name); 1307 li = stp_list_item_next(li); 1308 } 1309 return answer; 1310 } 1311 return NULL; 1312} 1313 1314#define LIST_FUNCTION(type, index) \ 1315stp_string_list_t * \ 1316stp_list_##type##_parameters(const stp_vars_t *v) \ 1317{ \ 1318 return stp_list_parameters(v, index); \ 1319} 1320 1321LIST_FUNCTION(string, STP_PARAMETER_TYPE_STRING_LIST) 1322LIST_FUNCTION(file, STP_PARAMETER_TYPE_FILE) 1323LIST_FUNCTION(float, STP_PARAMETER_TYPE_DOUBLE) 1324LIST_FUNCTION(int, STP_PARAMETER_TYPE_INT) 1325LIST_FUNCTION(dimension, STP_PARAMETER_TYPE_DIMENSION) 1326LIST_FUNCTION(boolean, STP_PARAMETER_TYPE_BOOLEAN) 1327LIST_FUNCTION(curve, STP_PARAMETER_TYPE_CURVE) 1328LIST_FUNCTION(array, STP_PARAMETER_TYPE_ARRAY) 1329LIST_FUNCTION(raw, STP_PARAMETER_TYPE_RAW) 1330 1331stp_parameter_activity_t 1332stp_get_parameter_active(const stp_vars_t *v, const char *parameter, 1333 stp_parameter_type_t p_type) 1334{ 1335 if (p_type >= STP_PARAMETER_TYPE_STRING_LIST && 1336 p_type < STP_PARAMETER_TYPE_INVALID) 1337 { 1338 const stp_list_t *list = v->params[p_type]; 1339 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1340 if (item) 1341 return ((const value_t *) stp_list_item_get_data(item))->active; 1342 else 1343 return 0; 1344 } 1345 return 0; 1346} 1347 1348#define GET_PARAMETER_ACTIVE_FUNCTION(type, index) \ 1349stp_parameter_activity_t \ 1350stp_get_##type##_parameter_active(const stp_vars_t *v, const char *parameter) \ 1351{ \ 1352 return stp_get_parameter_active(v, parameter, index); \ 1353} 1354 1355GET_PARAMETER_ACTIVE_FUNCTION(string, STP_PARAMETER_TYPE_STRING_LIST) 1356GET_PARAMETER_ACTIVE_FUNCTION(file, STP_PARAMETER_TYPE_FILE) 1357GET_PARAMETER_ACTIVE_FUNCTION(float, STP_PARAMETER_TYPE_DOUBLE) 1358GET_PARAMETER_ACTIVE_FUNCTION(int, STP_PARAMETER_TYPE_INT) 1359GET_PARAMETER_ACTIVE_FUNCTION(dimension, STP_PARAMETER_TYPE_DIMENSION) 1360GET_PARAMETER_ACTIVE_FUNCTION(boolean, STP_PARAMETER_TYPE_BOOLEAN) 1361GET_PARAMETER_ACTIVE_FUNCTION(curve, STP_PARAMETER_TYPE_CURVE) 1362GET_PARAMETER_ACTIVE_FUNCTION(array, STP_PARAMETER_TYPE_ARRAY) 1363GET_PARAMETER_ACTIVE_FUNCTION(raw, STP_PARAMETER_TYPE_RAW) 1364 1365void 1366stp_set_parameter_active(stp_vars_t *v, 1367 const char *parameter, 1368 stp_parameter_activity_t active, 1369 stp_parameter_type_t p_type) 1370{ 1371 if (p_type >= STP_PARAMETER_TYPE_STRING_LIST && 1372 p_type < STP_PARAMETER_TYPE_INVALID) 1373 { 1374 const stp_list_t *list = v->params[p_type]; 1375 const stp_list_item_t *item = stp_list_get_item_by_name(list, parameter); 1376 if (item && (active == STP_PARAMETER_ACTIVE || 1377 active == STP_PARAMETER_INACTIVE)) 1378 ((value_t *) stp_list_item_get_data(item))->active = active; 1379 } 1380} 1381 1382#define SET_PARAMETER_ACTIVE_FUNCTION(type, index) \ 1383void \ 1384stp_set_##type##_parameter_active(stp_vars_t *v, const char *parameter, \ 1385 stp_parameter_activity_t active) \ 1386{ \ 1387 stp_deprintf(STP_DBG_VARS, \ 1388 "stp_set_%s_parameter_active(0x%p, %s, %d)\n", \ 1389 #type, (const void *) v, parameter, active); \ 1390 stp_set_parameter_active(v, parameter, active, index); \ 1391} 1392 1393SET_PARAMETER_ACTIVE_FUNCTION(string, STP_PARAMETER_TYPE_STRING_LIST) 1394SET_PARAMETER_ACTIVE_FUNCTION(file, STP_PARAMETER_TYPE_FILE) 1395SET_PARAMETER_ACTIVE_FUNCTION(float, STP_PARAMETER_TYPE_DOUBLE) 1396SET_PARAMETER_ACTIVE_FUNCTION(int, STP_PARAMETER_TYPE_INT) 1397SET_PARAMETER_ACTIVE_FUNCTION(dimension, STP_PARAMETER_TYPE_DIMENSION) 1398SET_PARAMETER_ACTIVE_FUNCTION(boolean, STP_PARAMETER_TYPE_BOOLEAN) 1399SET_PARAMETER_ACTIVE_FUNCTION(curve, STP_PARAMETER_TYPE_CURVE) 1400SET_PARAMETER_ACTIVE_FUNCTION(array, STP_PARAMETER_TYPE_ARRAY) 1401SET_PARAMETER_ACTIVE_FUNCTION(raw, STP_PARAMETER_TYPE_RAW) 1402 1403void 1404stp_fill_parameter_settings(stp_parameter_t *desc, 1405 const stp_parameter_t *param) 1406{ 1407 if (param) 1408 { 1409 desc->p_type = param->p_type; 1410 desc->p_level = param->p_level; 1411 desc->p_class = param->p_class; 1412 desc->is_mandatory = param->is_mandatory; 1413 desc->is_active = param->is_active; 1414 desc->channel = param->channel; 1415 desc->verify_this_parameter = param->verify_this_parameter; 1416 desc->read_only = param->read_only; 1417 desc->name = param->name; 1418 STPI_ASSERT(param->text, NULL); 1419 desc->text = gettext(param->text); 1420 STPI_ASSERT(param->category, NULL); 1421 desc->category = gettext(param->category); 1422 desc->help = param->help ? gettext(param->help) : NULL; 1423 return; 1424 } 1425} 1426 1427void 1428stp_vars_copy(stp_vars_t *vd, const stp_vars_t *vs) 1429{ 1430 int i; 1431 1432 if (vs == vd) 1433 return; 1434 stp_set_driver(vd, stp_get_driver(vs)); 1435 stp_set_color_conversion(vd, stp_get_color_conversion(vs)); 1436 stp_set_left(vd, stp_get_left(vs)); 1437 stp_set_top(vd, stp_get_top(vs)); 1438 stp_set_width(vd, stp_get_width(vs)); 1439 stp_set_height(vd, stp_get_height(vs)); 1440 stp_set_page_width(vd, stp_get_page_width(vs)); 1441 stp_set_page_height(vd, stp_get_page_height(vs)); 1442 stp_set_outdata(vd, stp_get_outdata(vs)); 1443 stp_set_errdata(vd, stp_get_errdata(vs)); 1444 stp_set_outfunc(vd, stp_get_outfunc(vs)); 1445 stp_set_errfunc(vd, stp_get_errfunc(vs)); 1446 for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++) 1447 { 1448 stp_list_destroy(vd->params[i]); 1449 vd->params[i] = copy_value_list(vs->params[i]); 1450 } 1451 stp_list_destroy(vd->internal_data); 1452 vd->internal_data = copy_compdata_list(vs->internal_data); 1453 stp_set_verified(vd, stp_get_verified(vs)); 1454} 1455 1456void 1457stp_prune_inactive_options(stp_vars_t *v) 1458{ 1459 stp_parameter_list_t params = stp_get_parameter_list(v); 1460 int i; 1461 for (i = 0; i < STP_PARAMETER_TYPE_INVALID; i++) 1462 { 1463 stp_list_t *list = v->params[i]; 1464 stp_list_item_t *item = stp_list_get_start(list); 1465 while (item) 1466 { 1467 stp_list_item_t *next = stp_list_item_next(item); 1468 value_t *var = (value_t *)stp_list_item_get_data(item); 1469 if (var->active < STP_PARAMETER_DEFAULTED || 1470 !(stp_parameter_find(params, var->name))) 1471 stp_list_item_destroy(list, item); 1472 item = next; 1473 } 1474 } 1475 stp_parameter_list_destroy(params); 1476} 1477 1478stp_vars_t * 1479stp_vars_create_copy(const stp_vars_t *vs) 1480{ 1481 stp_vars_t *vd = stp_vars_create(); 1482 stp_vars_copy(vd, vs); 1483 return (vd); 1484} 1485 1486static const char * 1487param_namefunc(const void *item) 1488{ 1489 const stp_parameter_t *param = (const stp_parameter_t *)(item); 1490 return param->name; 1491} 1492 1493static const char * 1494param_longnamefunc(const void *item) 1495{ 1496 const stp_parameter_t *param = (const stp_parameter_t *) (item); 1497 return param->text; 1498} 1499 1500stp_parameter_list_t 1501stp_parameter_list_create(void) 1502{ 1503 stp_list_t *ret = stp_list_create(); 1504 stp_list_set_namefunc(ret, param_namefunc); 1505 stp_list_set_long_namefunc(ret, param_longnamefunc); 1506 return (stp_parameter_list_t) ret; 1507} 1508 1509void 1510stp_parameter_list_add_param(stp_parameter_list_t list, 1511 const stp_parameter_t *item) 1512{ 1513 stp_list_t *ilist = (stp_list_t *) list; 1514 stp_list_item_create(ilist, NULL, item); 1515} 1516 1517static void 1518debug_print_parameter_description(const stp_parameter_t *desc, const char *who, 1519 const stp_vars_t *v) 1520{ 1521 int i; 1522 char *curve; 1523 if (! (stp_get_debug_level() & STP_DBG_VARS)) 1524 return; 1525 stp_deprintf(STP_DBG_VARS, "Describe %s: vars 0x%p from %s type %d class %d level %d\n", 1526 desc->name, (const void *) v, who, 1527 desc->p_type, desc->p_class, desc->p_level); 1528 stp_deprintf(STP_DBG_VARS, " driver %s mandatory %d active %d channel %d verify %d ro %d\n", 1529 stp_get_driver(v), desc->is_mandatory, desc->is_active, 1530 desc->channel, desc->verify_this_parameter, desc->read_only); 1531 switch (desc->p_type) 1532 { 1533 case STP_PARAMETER_TYPE_STRING_LIST: 1534 stp_deprintf(STP_DBG_VARS, 1535 " String default: %s\n", 1536 desc->deflt.str ? desc->deflt.str : "(null)"); 1537 if (desc->bounds.str) 1538 for (i = 0; i < stp_string_list_count(desc->bounds.str); i++) 1539 { 1540 if (i == 0) 1541 stp_deprintf(STP_DBG_VARS, " Choices: %s\n", 1542 stp_string_list_param(desc->bounds.str, i)->name); 1543 else 1544 stp_deprintf(STP_DBG_VARS, " : %s\n", 1545 stp_string_list_param(desc->bounds.str, i)->name); 1546 } 1547 break; 1548 case STP_PARAMETER_TYPE_INT: 1549 stp_deprintf(STP_DBG_VARS, 1550 " Integer default: %d Bounds: %d %d\n", 1551 desc->deflt.integer, 1552 desc->bounds.integer.lower, desc->bounds.integer.upper); 1553 break; 1554 case STP_PARAMETER_TYPE_DIMENSION: 1555 stp_deprintf(STP_DBG_VARS, 1556 " Dimension default: %d Bounds: %d %d\n", 1557 desc->deflt.dimension, 1558 desc->bounds.dimension.lower, desc->bounds.dimension.upper); 1559 break; 1560 case STP_PARAMETER_TYPE_BOOLEAN: 1561 stp_deprintf(STP_DBG_VARS, 1562 " Boolean default: %d\n", desc->deflt.boolean); 1563 break; 1564 case STP_PARAMETER_TYPE_DOUBLE: 1565 stp_deprintf(STP_DBG_VARS, 1566 " Double default: %f Bounds: %f %f\n", 1567 desc->deflt.dbl, 1568 desc->bounds.dbl.lower, desc->bounds.dbl.upper); 1569 break; 1570 case STP_PARAMETER_TYPE_FILE: 1571 stp_deprintf(STP_DBG_VARS, " File (no default)\n"); 1572 break; 1573 case STP_PARAMETER_TYPE_RAW: 1574 stp_deprintf(STP_DBG_VARS, " Raw (no default)\n"); 1575 break; 1576 case STP_PARAMETER_TYPE_CURVE: 1577 curve = stp_curve_write_string(desc->deflt.curve); 1578 stp_deprintf(STP_DBG_VARS, 1579 " Curve default: %s\n", curve); 1580 stp_free(curve); 1581 curve = stp_curve_write_string(desc->bounds.curve); 1582 stp_deprintf(STP_DBG_VARS, 1583 " bounds: %s\n", curve); 1584 stp_free(curve); 1585 break; 1586 case STP_PARAMETER_TYPE_ARRAY: 1587 stp_deprintf(STP_DBG_VARS, " Array\n"); 1588 break; 1589 case STP_PARAMETER_TYPE_INVALID: 1590 stp_deprintf(STP_DBG_VARS, " *** Invalid ***\n"); 1591 break; 1592 default: 1593 stp_deprintf(STP_DBG_VARS, " Unknown type!\n"); 1594 } 1595} 1596 1597void 1598stp_describe_parameter(const stp_vars_t *v, const char *name, 1599 stp_parameter_t *description) 1600{ 1601 description->p_type = STP_PARAMETER_TYPE_INVALID; 1602/* Set these to NULL in case stpi_*_describe_parameter() doesn't */ 1603 description->bounds.str = NULL; 1604 description->deflt.str = NULL; 1605 stp_printer_describe_parameter(v, name, description); 1606 if (description->p_type != STP_PARAMETER_TYPE_INVALID) 1607 { 1608 debug_print_parameter_description(description, "driver", v); 1609 return; 1610 } 1611 stp_color_describe_parameter(v, name, description); 1612 if (description->p_type != STP_PARAMETER_TYPE_INVALID) 1613 { 1614 debug_print_parameter_description(description, "color", v); 1615 return; 1616 } 1617 stp_dither_describe_parameter(v, name, description); 1618 if (description->p_type != STP_PARAMETER_TYPE_INVALID) 1619 { 1620 debug_print_parameter_description(description, "dither", v); 1621 return; 1622 } 1623 stpi_describe_generic_parameter(v, name, description); 1624 if (description->p_type != STP_PARAMETER_TYPE_INVALID) 1625 debug_print_parameter_description(description, "generic", v); 1626 else 1627 stp_deprintf(STP_DBG_VARS, "Describing invalid parameter %s\n", name); 1628} 1629 1630stp_string_list_t * 1631stp_parameter_get_categories(const stp_vars_t *v, const stp_parameter_t *desc) 1632{ 1633 const char *dptr; 1634 stp_string_list_t *answer; 1635 int count = 0; 1636 if (!v || !desc || !(desc->category)) 1637 return NULL; 1638 answer = stp_string_list_create(); 1639 dptr = desc->category; 1640 while (dptr) 1641 { 1642 const char *xptr = strchr(dptr, '='); 1643 if (xptr) 1644 { 1645 char *name = stp_strndup(dptr, xptr - dptr); 1646 char *text; 1647 dptr = xptr + 1; 1648 xptr = strchr(dptr, ','); 1649 if (xptr) 1650 { 1651 text = stp_strndup(dptr, xptr - dptr); 1652 dptr = xptr + 1; 1653 } 1654 else 1655 { 1656 text = stp_strdup(dptr); 1657 dptr = NULL; 1658 } 1659 stp_string_list_add_string(answer, name, text); 1660 stp_free(name); 1661 stp_free(text); 1662 count++; 1663 } 1664 else 1665 dptr = NULL; 1666 } 1667 if (count == 0) 1668 { 1669 stp_string_list_destroy(answer); 1670 return NULL; 1671 } 1672 else 1673 return answer; 1674} 1675 1676char * 1677stp_parameter_get_category(const stp_vars_t *v, const stp_parameter_t *desc, 1678 const char *category) 1679{ 1680 const char *dptr; 1681 char *cptr; 1682 int len; 1683 if (!v || !desc || !(desc->category) || !category) 1684 return NULL; 1685 dptr = desc->category; 1686 stp_asprintf(&cptr, "%s=", category); 1687 len = stp_strlen(cptr); 1688 while (dptr) 1689 { 1690 if (strncmp(dptr, cptr, len) == 0) 1691 { 1692 const char *xptr; 1693 char *answer; 1694 dptr += len; 1695 xptr = strchr(dptr, ','); 1696 if (xptr) 1697 answer = stp_strndup(dptr, xptr - dptr); 1698 else 1699 answer = stp_strdup(dptr); 1700 stp_free(cptr); 1701 return answer; 1702 } 1703 dptr = strchr(dptr, ','); 1704 if (dptr) 1705 dptr++; 1706 } 1707 return NULL; 1708} 1709 1710int 1711stp_parameter_has_category_value(const stp_vars_t *v, 1712 const stp_parameter_t *desc, 1713 const char *category, const char *value) 1714{ 1715 const char *dptr; 1716 char *cptr; 1717 int answer = 0; 1718 if (!v || !desc || !category) 1719 return -1; 1720 cptr = stp_parameter_get_category(v, desc, category); 1721 if (cptr == NULL) 1722 return 0; 1723 if (value == NULL || strcmp(value, cptr) == 0) 1724 answer = 1; 1725 stp_free(cptr); 1726 return answer; 1727} 1728 1729const stp_parameter_t * 1730stp_parameter_find_in_settings(const stp_vars_t *v, const char *name) 1731{ 1732 stp_parameter_list_t param_list = stp_get_parameter_list(v); 1733 const stp_parameter_t *param = stp_parameter_find(param_list, name); 1734 stp_parameter_list_destroy(param_list); 1735 return param; 1736} 1737 1738size_t 1739stp_parameter_list_count(stp_const_parameter_list_t list) 1740{ 1741 const stp_list_t *ilist = (const stp_list_t *)list; 1742 return stp_list_get_length(ilist); 1743} 1744 1745const stp_parameter_t * 1746stp_parameter_find(stp_const_parameter_list_t list, const char *name) 1747{ 1748 const stp_list_t *ilist = (const stp_list_t *)list; 1749 const stp_list_item_t *item = stp_list_get_item_by_name(ilist, name); 1750 if (item) 1751 return (const stp_parameter_t *) stp_list_item_get_data(item); 1752 else 1753 return NULL; 1754} 1755 1756const stp_parameter_t * 1757stp_parameter_list_param(stp_const_parameter_list_t list, size_t item) 1758{ 1759 const stp_list_t *ilist = (const stp_list_t *)list; 1760 if (item >= stp_list_get_length(ilist)) 1761 return NULL; 1762 else 1763 return (const stp_parameter_t *) 1764 stp_list_item_get_data(stp_list_get_item_by_index(ilist, item)); 1765} 1766 1767void 1768stp_parameter_list_destroy(stp_parameter_list_t list) 1769{ 1770 stp_list_destroy((stp_list_t *)list); 1771} 1772 1773stp_parameter_list_t 1774stp_parameter_list_copy(stp_const_parameter_list_t list) 1775{ 1776 stp_list_t *ret = stp_parameter_list_create(); 1777 int i; 1778 size_t count = stp_parameter_list_count(list); 1779 for (i = 0; i < count; i++) 1780 stp_list_item_create(ret, NULL, stp_parameter_list_param(list, i)); 1781 return (stp_parameter_list_t) ret; 1782} 1783 1784void 1785stp_parameter_list_append(stp_parameter_list_t list, 1786 stp_const_parameter_list_t append) 1787{ 1788 int i; 1789 stp_list_t *ilist = (stp_list_t *)list; 1790 size_t count = stp_parameter_list_count(append); 1791 for (i = 0; i < count; i++) 1792 { 1793 const stp_parameter_t *param = stp_parameter_list_param(append, i); 1794 if (!stp_list_get_item_by_name(ilist, param->name)) 1795 stp_list_item_create(ilist, NULL, param); 1796 } 1797} 1798 1799static void 1800fill_vars_from_xmltree(stp_mxml_node_t *prop, stp_mxml_node_t *root, 1801 stp_vars_t *v) 1802{ 1803#ifdef HAVE_LOCALE_H 1804 char *locale = stp_strdup(setlocale(LC_ALL, NULL)); 1805 setlocale(LC_ALL, "C"); 1806#endif 1807 while (prop) 1808 { 1809 if (prop->type == STP_MXML_ELEMENT && 1810 !strcmp(prop->value.element.name, "parameter") && 1811 (prop->child || stp_mxmlElementGetAttr(prop, "name"))) 1812 { 1813 stp_mxml_node_t *child = prop->child; 1814 const char *prop_name = prop->value.element.name; 1815 const char *p_type = stp_mxmlElementGetAttr(prop, "type"); 1816 const char *p_name = stp_mxmlElementGetAttr(prop, "name"); 1817 if (!strcmp(prop_name, "parameter") && (!p_type || !p_name)) 1818 stp_erprintf("Bad property found!\n"); 1819 else if (!strcmp(prop_name, "parameter")) 1820 { 1821 const char *active = stp_mxmlElementGetAttr(prop, "active"); 1822 const char *cref = stp_mxmlElementGetAttr(prop, "ref"); 1823 stp_mxml_node_t *cnode = child; 1824 stp_parameter_type_t type = STP_PARAMETER_TYPE_INVALID; 1825 if (cref && root) 1826 { 1827 cnode = stp_mxmlFindElement(root, root, "namedParam", 1828 "name", cref, 1829 STP_MXML_DESCEND); 1830 STPI_ASSERT(cnode && cnode->type == STP_MXML_ELEMENT && 1831 cnode->child, v); 1832 stp_deprintf(STP_DBG_XML, "Found parameter ref %s\n", cref); 1833 cnode = cnode->child; 1834 } 1835 if (strcmp(p_type, "float") == 0) 1836 { 1837 if (cnode->type == STP_MXML_TEXT) 1838 { 1839 stp_set_float_parameter 1840 (v, p_name, stp_xmlstrtod(cnode->value.text.string)); 1841 type = STP_PARAMETER_TYPE_DOUBLE; 1842 if (stp_get_debug_level() & STP_DBG_XML) 1843 stp_deprintf(STP_DBG_XML, " Set float '%s' to '%s' (%f)\n", 1844 p_name, cnode->value.text.string, 1845 stp_get_float_parameter(v, p_name)); 1846 } 1847 } 1848 else if (strcmp(p_type, "integer") == 0) 1849 { 1850 if (cnode->type == STP_MXML_TEXT) 1851 { 1852 stp_set_int_parameter 1853 (v, p_name, (int) stp_xmlstrtol(cnode->value.text.string)); 1854 type = STP_PARAMETER_TYPE_DOUBLE; 1855 if (stp_get_debug_level() & STP_DBG_XML) 1856 stp_deprintf(STP_DBG_XML, " Set int '%s' to '%s' (%d)\n", 1857 p_name, cnode->value.text.string, 1858 stp_get_int_parameter(v, p_name)); 1859 } 1860 } 1861 else if (strcmp(p_type, "dimension") == 0) 1862 { 1863 if (cnode->type == STP_MXML_TEXT) 1864 { 1865 stp_set_dimension_parameter 1866 (v, p_name, (int) stp_xmlstrtol(cnode->value.text.string)); 1867 type = STP_PARAMETER_TYPE_DOUBLE; 1868 if (stp_get_debug_level() & STP_DBG_XML) 1869 stp_deprintf(STP_DBG_XML, " Set dimension '%s' to '%s' (%d)\n", 1870 p_name, cnode->value.text.string, 1871 stp_get_dimension_parameter(v, p_name)); 1872 } 1873 } 1874 else if (strcmp(p_type, "boolean") == 0) 1875 { 1876 if (cnode->type == STP_MXML_TEXT) 1877 { 1878 stp_set_boolean_parameter 1879 (v, p_name, (int) stp_xmlstrtol(cnode->value.text.string)); 1880 type = STP_PARAMETER_TYPE_DOUBLE; 1881 if (stp_get_debug_level() & STP_DBG_XML) 1882 stp_deprintf(STP_DBG_XML, " Set bool '%s' to '%s' (%d)\n", 1883 p_name, cnode->value.text.string, 1884 stp_get_boolean_parameter(v, p_name)); 1885 } 1886 } 1887 else if (strcmp(p_type, "string") == 0) 1888 { 1889 if (cnode->type == STP_MXML_TEXT) 1890 { 1891 stp_set_string_parameter 1892 (v, p_name, cnode->value.text.string); 1893 type = STP_PARAMETER_TYPE_DOUBLE; 1894 if (stp_get_debug_level() & STP_DBG_XML) 1895 stp_deprintf(STP_DBG_XML, " Set string '%s' to '%s' (%s)\n", 1896 p_name, cnode->value.text.string, 1897 stp_get_string_parameter(v, p_name)); 1898 } 1899 } 1900 else if (strcmp(p_type, "file") == 0) 1901 { 1902 if (cnode->type == STP_MXML_TEXT) 1903 { 1904 stp_set_file_parameter 1905 (v, p_name, cnode->value.text.string); 1906 type = STP_PARAMETER_TYPE_DOUBLE; 1907 if (stp_get_debug_level() & STP_DBG_XML) 1908 stp_deprintf(STP_DBG_XML, " Set file '%s' to '%s' (%s)\n", 1909 p_name, cnode->value.text.string, 1910 stp_get_file_parameter(v, p_name)); 1911 } 1912 } 1913 else if (strcmp(p_type, "raw") == 0) 1914 { 1915 if (cnode->type == STP_MXML_TEXT) 1916 { 1917 stp_raw_t *raw = stp_xmlstrtoraw(cnode->value.text.string); 1918 if (raw) 1919 { 1920 stp_set_raw_parameter(v, p_name, raw->data,raw->bytes); 1921 type = STP_PARAMETER_TYPE_DOUBLE; 1922 stp_deprintf(STP_DBG_XML, " Set raw '%s' to '%s'\n", 1923 p_name, cnode->value.text.string); 1924 stp_free((void *) raw->data); 1925 stp_free(raw); 1926 } 1927 } 1928 } 1929 else if (strcmp(p_type, "curve") == 0) 1930 { 1931 stp_curve_t *curve; 1932 while (cnode->type != STP_MXML_ELEMENT && cnode->next) 1933 cnode = cnode->next; 1934 STPI_ASSERT(cnode, v); 1935 curve = stp_curve_create_from_xmltree(cnode); 1936 STPI_ASSERT(curve, v); 1937 stp_set_curve_parameter(v, p_name, curve); 1938 type = STP_PARAMETER_TYPE_DOUBLE; 1939 if (stp_get_debug_level() & STP_DBG_XML) 1940 { 1941 char *cv = stp_curve_write_string(curve); 1942 stp_deprintf(STP_DBG_XML, " Set curve '%s' (%s)\n", 1943 p_name, cv); 1944 stp_free(cv); 1945 } 1946 stp_curve_destroy(curve); 1947 } 1948 else if (strcmp(p_type, "array") == 0) 1949 { 1950 stp_array_t *array; 1951 while (cnode->type != STP_MXML_ELEMENT && cnode->next) 1952 cnode = cnode->next; 1953 STPI_ASSERT(cnode, v); 1954 array = stp_array_create_from_xmltree(cnode); 1955 STPI_ASSERT(array, v); 1956 type = STP_PARAMETER_TYPE_DOUBLE; 1957 stp_set_array_parameter(v, p_name, array); 1958 stp_deprintf(STP_DBG_XML, " Set array '%s'\n", p_name); 1959 stp_array_destroy(array); 1960 } 1961 else 1962 { 1963 stp_erprintf("Bad property %s type %s\n", p_name, p_type); 1964 } 1965 if (active && type != STP_PARAMETER_TYPE_INVALID) 1966 { 1967 if (strcmp(active, "active") == 0) 1968 stp_set_parameter_active(v, p_name, STP_PARAMETER_ACTIVE, type); 1969 else if (strcmp(active, "inactive") == 0) 1970 stp_set_parameter_active(v, p_name, STP_PARAMETER_INACTIVE, type); 1971 else if (strcmp(active, "default") == 0) 1972 stp_set_parameter_active(v, p_name, STP_PARAMETER_DEFAULTED, type); 1973 } 1974 1975 } 1976 else if (child->type == STP_MXML_TEXT) 1977 { 1978 if (!strcmp(prop_name, "driver")) 1979 stp_set_driver(v, child->value.text.string); 1980 else if (!strcmp(prop_name, "color_conversion")) 1981 stp_set_color_conversion(v, child->value.text.string); 1982 else if (!strcmp(prop_name, "left")) 1983 stp_set_left(v, stp_xmlstrtol(child->value.text.string)); 1984 else if (!strcmp(prop_name, "top")) 1985 stp_set_top(v, stp_xmlstrtol(child->value.text.string)); 1986 else if (!strcmp(prop_name, "width")) 1987 stp_set_width(v, stp_xmlstrtol(child->value.text.string)); 1988 else if (!strcmp(prop_name, "height")) 1989 stp_set_height(v, stp_xmlstrtol(child->value.text.string)); 1990 else if (!strcmp(prop_name, "page_width")) 1991 stp_set_page_width(v, stp_xmlstrtol(child->value.text.string)); 1992 else if (!strcmp(prop_name, "page_height")) 1993 stp_set_page_height(v, stp_xmlstrtol(child->value.text.string)); 1994 } 1995 } 1996 prop = prop->next; 1997 } 1998#ifdef HAVE_LOCALE_H 1999 setlocale(LC_ALL, locale); 2000 stp_free(locale); 2001#endif 2002} 2003 2004void 2005stp_vars_fill_from_xmltree(stp_mxml_node_t *prop, stp_vars_t *v) 2006{ 2007 fill_vars_from_xmltree(prop, NULL, v); 2008} 2009 2010stp_vars_t * 2011stp_vars_create_from_xmltree(stp_mxml_node_t *da) 2012{ 2013 stp_vars_t *v = stp_vars_create(); 2014 fill_vars_from_xmltree(da, NULL, v); 2015 return v; 2016} 2017 2018void 2019stp_vars_fill_from_xmltree_ref(stp_mxml_node_t *prop, stp_mxml_node_t *root, 2020 stp_vars_t *v) 2021{ 2022 fill_vars_from_xmltree(prop, root, v); 2023} 2024 2025stp_vars_t * 2026stp_vars_create_from_xmltree_ref(stp_mxml_node_t *da, stp_mxml_node_t *root) 2027{ 2028 stp_vars_t *v = stp_vars_create(); 2029 fill_vars_from_xmltree(da, root, v); 2030 return v; 2031} 2032 2033static void 2034add_text_node(stp_mxml_node_t *node, const char *element, const char *value) 2035{ 2036 if (value) 2037 stp_mxmlNewOpaque(stp_mxmlNewElement(node, element), value); 2038} 2039 2040stp_mxml_node_t * 2041stp_xmltree_create_from_vars(const stp_vars_t *v) 2042{ 2043 stp_mxml_node_t *varnode; 2044 int i; 2045 if (!v) 2046 return NULL; 2047 varnode = stp_mxmlNewElement(NULL, "vars"); 2048 add_text_node(varnode, "driver", stp_get_driver(v)); 2049 add_text_node(varnode, "color_conversion", stp_get_color_conversion(v)); 2050 stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "left"), stp_get_left(v)); 2051 stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "top"), stp_get_top(v)); 2052 stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "width"), stp_get_width(v)); 2053 stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "height"), stp_get_height(v)); 2054 stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "page_width"), stp_get_page_width(v)); 2055 stp_mxmlNewInteger(stp_mxmlNewElement(varnode, "page_height"), stp_get_page_height(v)); 2056 for (i = STP_PARAMETER_TYPE_STRING_LIST; i < STP_PARAMETER_TYPE_INVALID; i++) 2057 { 2058 stp_string_list_t *list = stp_list_parameters(v, i); 2059 if (list) 2060 { 2061 int j; 2062 int count = stp_string_list_count(list); 2063 for (j = 0; j < count; j++) 2064 { 2065 const stp_param_string_t *pstr = stp_string_list_param(list, j); 2066 const char *name = pstr->name; 2067 char *data; 2068 stp_mxml_node_t *node = stp_mxmlNewElement(varnode, "parameter"); 2069 stp_parameter_activity_t active = 2070 stp_get_parameter_active(v, name, i); 2071 stp_mxmlElementSetAttr(node, "name", name); 2072 stp_mxmlElementSetAttr(node, "active", 2073 (active == STP_PARAMETER_INACTIVE ? 2074 "inactive" : 2075 (active == STP_PARAMETER_DEFAULTED ? 2076 "default" : "active"))); 2077 switch (i) 2078 { 2079 case STP_PARAMETER_TYPE_STRING_LIST: 2080 stp_mxmlElementSetAttr(node, "type", "string"); 2081 data = stp_strtoxmlstr(stp_get_string_parameter(v, name)); 2082 if (data) 2083 { 2084 stp_mxmlNewOpaque(node, data); 2085 stp_free(data); 2086 } 2087 break; 2088 case STP_PARAMETER_TYPE_INT: 2089 stp_mxmlElementSetAttr(node, "type", "integer"); 2090 stp_mxmlNewInteger(node, stp_get_int_parameter(v, name)); 2091 break; 2092 case STP_PARAMETER_TYPE_BOOLEAN: 2093 stp_mxmlElementSetAttr(node, "type", "boolean"); 2094 stp_mxmlNewInteger(node, stp_get_boolean_parameter(v, name)); 2095 break; 2096 case STP_PARAMETER_TYPE_DOUBLE: 2097 stp_mxmlElementSetAttr(node, "type", "float"); 2098 stp_mxmlNewReal(node, stp_get_float_parameter(v, name)); 2099 break; 2100 case STP_PARAMETER_TYPE_CURVE: 2101 stp_mxmlElementSetAttr(node, "type", "curve"); 2102 stp_mxmlAdd(node, STP_MXML_ADD_AFTER, NULL, 2103 stp_xmltree_create_from_curve(stp_get_curve_parameter(v, name))); 2104 break; 2105 case STP_PARAMETER_TYPE_FILE: 2106 stp_mxmlElementSetAttr(node, "type", "file"); 2107 data = stp_strtoxmlstr(stp_get_file_parameter(v, name)); 2108 if (data) 2109 { 2110 stp_mxmlNewOpaque(node, data); 2111 stp_free(data); 2112 } 2113 break; 2114 case STP_PARAMETER_TYPE_RAW: 2115 stp_mxmlElementSetAttr(node, "type", "raw"); 2116 data = stp_rawtoxmlstr(stp_get_raw_parameter(v, name)); 2117 if (data) 2118 { 2119 stp_mxmlNewOpaque(node, data); 2120 stp_free(data); 2121 } 2122 break; 2123 case STP_PARAMETER_TYPE_ARRAY: 2124 stp_mxmlElementSetAttr(node, "type", "array"); 2125 stp_mxmlAdd(node, STP_MXML_ADD_AFTER, NULL, 2126 stp_xmltree_create_from_array(stp_get_array_parameter(v, name))); 2127 break; 2128 case STP_PARAMETER_TYPE_DIMENSION: 2129 stp_mxmlElementSetAttr(node, "type", "dimension"); 2130 stp_mxmlNewInteger(node, stp_get_dimension_parameter(v, name)); 2131 break; 2132 default: 2133 stp_mxmlElementSetAttr(node, "type", "INVALID!"); 2134 break; 2135 } 2136 } 2137 stp_string_list_destroy(list); 2138 } 2139 } 2140 return varnode; 2141} 2142