00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 #include <gimp-print/gimp-print.h>
00033 #include "gimp-print-internal.h"
00034 #include <gimp-print/gimp-print-intl-internal.h>
00035 #include <math.h>
00036 #ifdef HAVE_LIMITS_H
00037 #include <limits.h>
00038 #endif
00039 #include <string.h>
00040 #include <stdlib.h>
00041
00042 #define FMIN(a, b) ((a) < (b) ? (a) : (b))
00043
00044
00045 static void stpi_printer_freefunc(void *item);
00046 static const char* stpi_printer_namefunc(const void *item);
00047 static const char* stpi_printer_long_namefunc(const void *item);
00048
00049 static stp_list_t *printer_list = NULL;
00050
00051 struct stp_printer
00052 {
00053 const char *driver;
00054 char *long_name;
00055 char *family;
00056 char *manufacturer;
00057 int model;
00058 const stp_printfuncs_t *printfuncs;
00059 stp_vars_t *printvars;
00060 };
00061
00062 static int
00063 stpi_init_printer_list(void)
00064 {
00065 if(printer_list)
00066 stp_list_destroy(printer_list);
00067 printer_list = stp_list_create();
00068 stp_list_set_freefunc(printer_list, stpi_printer_freefunc);
00069 stp_list_set_namefunc(printer_list, stpi_printer_namefunc);
00070 stp_list_set_long_namefunc(printer_list, stpi_printer_long_namefunc);
00071
00072
00073 return 0;
00074 }
00075
00076 int
00077 stp_printer_model_count(void)
00078 {
00079 if (printer_list == NULL)
00080 {
00081 stp_erprintf("No printer drivers found: "
00082 "are STP_DATA_PATH and STP_MODULE_PATH correct?\n");
00083 stpi_init_printer_list();
00084 }
00085 return stp_list_get_length(printer_list);
00086 }
00087
00088 static void
00089 null_printer(void)
00090 {
00091 stp_erprintf("Null stp_printer_t! Please report this bug.\n");
00092 stp_abort();
00093 }
00094
00095 static inline void
00096 check_printer(const stp_printer_t *p)
00097 {
00098 if (p == NULL)
00099 null_printer();
00100 }
00101
00102 const stp_printer_t *
00103 stp_get_printer_by_index(int idx)
00104 {
00105 stp_list_item_t *printer;
00106 if (printer_list == NULL)
00107 {
00108 stp_erprintf("No printer drivers found: "
00109 "are STP_DATA_PATH and STP_MODULE_PATH correct?\n");
00110 stpi_init_printer_list();
00111 }
00112 printer = stp_list_get_item_by_index(printer_list, idx);
00113 if (printer == NULL)
00114 return NULL;
00115 return (const stp_printer_t *) stp_list_item_get_data(printer);
00116 }
00117
00118 static void
00119 stpi_printer_freefunc(void *item)
00120 {
00121 stp_printer_t *printer = (stp_printer_t *) item;
00122 stp_free(printer->long_name);
00123 stp_free(printer->family);
00124 stp_free(printer);
00125 }
00126
00127 const char *
00128 stp_printer_get_driver(const stp_printer_t *printer)
00129 {
00130 return printer->driver;
00131 }
00132
00133 static const char *
00134 stpi_printer_namefunc(const void *item)
00135 {
00136 const stp_printer_t *printer = (const stp_printer_t *) item;
00137 return printer->driver;
00138 }
00139
00140 const char *
00141 stp_printer_get_long_name(const stp_printer_t *printer)
00142 {
00143 return printer->long_name;
00144 }
00145
00146 static const char *
00147 stpi_printer_long_namefunc(const void *item)
00148 {
00149 const stp_printer_t *printer = (const stp_printer_t *) item;
00150 return printer->long_name;
00151 }
00152
00153 const char *
00154 stp_printer_get_family(const stp_printer_t *printer)
00155 {
00156 return printer->family;
00157 }
00158
00159 const char *
00160 stp_printer_get_manufacturer(const stp_printer_t *printer)
00161 {
00162 return printer->manufacturer;
00163 }
00164
00165 int
00166 stp_printer_get_model(const stp_printer_t *printer)
00167 {
00168 return printer->model;
00169 }
00170
00171 static inline const stp_printfuncs_t *
00172 stpi_get_printfuncs(const stp_printer_t *printer)
00173 {
00174 return printer->printfuncs;
00175 }
00176
00177 const stp_vars_t *
00178 stp_printer_get_defaults(const stp_printer_t *printer)
00179 {
00180 return printer->printvars;
00181 }
00182
00183
00184 const stp_printer_t *
00185 stp_get_printer_by_long_name(const char *long_name)
00186 {
00187 stp_list_item_t *printer_item;
00188 if (printer_list == NULL)
00189 {
00190 stp_erprintf("No printer drivers found: "
00191 "are STP_DATA_PATH and STP_MODULE_PATH correct?\n");
00192 stpi_init_printer_list();
00193 }
00194 printer_item = stp_list_get_item_by_long_name(printer_list, long_name);
00195 if (!printer_item)
00196 return NULL;
00197 return (const stp_printer_t *) stp_list_item_get_data(printer_item);
00198 }
00199
00200 const stp_printer_t *
00201 stp_get_printer_by_driver(const char *driver)
00202 {
00203 stp_list_item_t *printer_item;
00204 if (printer_list == NULL)
00205 {
00206 stp_erprintf("No printer drivers found: "
00207 "are STP_DATA_PATH and STP_MODULE_PATH correct?\n");
00208 stpi_init_printer_list();
00209 }
00210 printer_item = stp_list_get_item_by_name(printer_list, driver);
00211 if (!printer_item)
00212 return NULL;
00213 return (const stp_printer_t *) stp_list_item_get_data(printer_item);
00214 }
00215
00216 int
00217 stp_get_printer_index_by_driver(const char *driver)
00218 {
00219
00220 int idx = 0;
00221 for (idx = 0; idx < stp_printer_model_count(); idx++)
00222 {
00223 const stp_printer_t *printer = stp_get_printer_by_index(idx);
00224 if (!strcmp(stp_printer_get_driver(printer), driver))
00225 return idx;
00226 }
00227 return -1;
00228 }
00229
00230 const stp_printer_t *
00231 stp_get_printer(const stp_vars_t *v)
00232 {
00233 return stp_get_printer_by_driver(stp_get_driver(v));
00234 }
00235
00236 int
00237 stp_get_model_id(const stp_vars_t *v)
00238 {
00239 const stp_printer_t *printer = stp_get_printer_by_driver(stp_get_driver(v));
00240 return printer->model;
00241 }
00242
00243 stp_parameter_list_t
00244 stp_printer_list_parameters(const stp_vars_t *v)
00245 {
00246 const stp_printfuncs_t *printfuncs =
00247 stpi_get_printfuncs(stp_get_printer(v));
00248 return (printfuncs->list_parameters)(v);
00249 }
00250
00251 void
00252 stp_printer_describe_parameter(const stp_vars_t *v, const char *name,
00253 stp_parameter_t *description)
00254 {
00255 const stp_printfuncs_t *printfuncs =
00256 stpi_get_printfuncs(stp_get_printer(v));
00257 (printfuncs->parameters)(v, name, description);
00258 }
00259
00260 static void
00261 set_printer_defaults(stp_vars_t *v, int core_only)
00262 {
00263 stp_parameter_list_t *params;
00264 int count;
00265 int i;
00266 stp_parameter_t desc;
00267 params = stp_get_parameter_list(v);
00268 count = stp_parameter_list_count(params);
00269 for (i = 0; i < count; i++)
00270 {
00271 const stp_parameter_t *p = stp_parameter_list_param(params, i);
00272 if (p->is_mandatory &&
00273 (!core_only || p->p_class == STP_PARAMETER_CLASS_CORE))
00274 {
00275 stp_describe_parameter(v, p->name, &desc);
00276 switch (p->p_type)
00277 {
00278 case STP_PARAMETER_TYPE_STRING_LIST:
00279 stp_set_string_parameter(v, p->name, desc.deflt.str);
00280 stp_set_string_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00281 break;
00282 case STP_PARAMETER_TYPE_DOUBLE:
00283 stp_set_float_parameter(v, p->name, desc.deflt.dbl);
00284 stp_set_float_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00285 break;
00286 case STP_PARAMETER_TYPE_INT:
00287 stp_set_int_parameter(v, p->name, desc.deflt.integer);
00288 stp_set_int_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00289 break;
00290 case STP_PARAMETER_TYPE_BOOLEAN:
00291 stp_set_boolean_parameter(v, p->name, desc.deflt.boolean);
00292 stp_set_boolean_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00293 break;
00294 case STP_PARAMETER_TYPE_CURVE:
00295 stp_set_curve_parameter(v, p->name, desc.deflt.curve);
00296 stp_set_curve_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00297 break;
00298 case STP_PARAMETER_TYPE_ARRAY:
00299 stp_set_array_parameter(v, p->name, desc.deflt.array);
00300 stp_set_array_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00301 break;
00302 default:
00303 break;
00304 }
00305 stp_parameter_description_destroy(&desc);
00306 }
00307 }
00308 stp_parameter_list_destroy(params);
00309 }
00310
00311 void
00312 stp_set_printer_defaults(stp_vars_t *v, const stp_printer_t *printer)
00313 {
00314 stp_set_driver(v, stp_printer_get_driver(printer));
00315 set_printer_defaults(v, 0);
00316 }
00317
00318 void
00319 stp_initialize_printer_defaults(void)
00320 {
00321 stp_list_item_t *printer_item;
00322 if (printer_list == NULL)
00323 {
00324 stpi_init_printer_list();
00325 stp_deprintf
00326 (STP_DBG_PRINTERS,
00327 "stpi_family_register(): initialising printer_list...\n");
00328 }
00329 printer_item = stp_list_get_start(printer_list);
00330 while (printer_item)
00331 {
00332 set_printer_defaults
00333 (((stp_printer_t *)(stp_list_item_get_data(printer_item)))->printvars, 1);
00334 printer_item = stp_list_item_next(printer_item);
00335 }
00336 }
00337
00338 void
00339 stp_get_media_size(const stp_vars_t *v, int *width, int *height)
00340 {
00341 const stp_printfuncs_t *printfuncs =
00342 stpi_get_printfuncs(stp_get_printer(v));
00343 (printfuncs->media_size)(v, width, height);
00344 }
00345
00346 void
00347 stp_get_imageable_area(const stp_vars_t *v,
00348 int *left, int *right, int *bottom, int *top)
00349 {
00350 const stp_printfuncs_t *printfuncs =
00351 stpi_get_printfuncs(stp_get_printer(v));
00352 (printfuncs->imageable_area)(v, left, right, bottom, top);
00353 }
00354
00355 void
00356 stp_get_size_limit(const stp_vars_t *v, int *max_width, int *max_height,
00357 int *min_width, int *min_height)
00358 {
00359 const stp_printfuncs_t *printfuncs =
00360 stpi_get_printfuncs(stp_get_printer(v));
00361 (printfuncs->limit)(v, max_width, max_height, min_width,min_height);
00362 }
00363
00364 void
00365 stp_describe_resolution(const stp_vars_t *v, int *x, int *y)
00366 {
00367 const stp_printfuncs_t *printfuncs =
00368 stpi_get_printfuncs(stp_get_printer(v));
00369 (printfuncs->describe_resolution)(v, x, y);
00370 }
00371
00372 const char *
00373 stp_describe_output(const stp_vars_t *v)
00374 {
00375 const stp_printfuncs_t *printfuncs =
00376 stpi_get_printfuncs(stp_get_printer(v));
00377 return (printfuncs->describe_output)(v);
00378 }
00379
00380 int
00381 stp_verify(stp_vars_t *v)
00382 {
00383 const stp_printfuncs_t *printfuncs =
00384 stpi_get_printfuncs(stp_get_printer(v));
00385 stp_vars_t *nv = stp_vars_create_copy(v);
00386 int status;
00387 stp_prune_inactive_options(nv);
00388 status = (printfuncs->verify)(nv);
00389 stp_set_verified(v, stp_get_verified(nv));
00390 stp_vars_destroy(nv);
00391 return status;
00392 }
00393
00394 int
00395 stp_print(const stp_vars_t *v, stp_image_t *image)
00396 {
00397 const stp_printfuncs_t *printfuncs =
00398 stpi_get_printfuncs(stp_get_printer(v));
00399 return (printfuncs->print)(v, image);
00400 }
00401
00402 int
00403 stp_start_job(const stp_vars_t *v, stp_image_t *image)
00404 {
00405 const stp_printfuncs_t *printfuncs =
00406 stpi_get_printfuncs(stp_get_printer(v));
00407 if (!stp_get_string_parameter(v, "JobMode") ||
00408 strcmp(stp_get_string_parameter(v, "JobMode"), "Page") == 0)
00409 return 1;
00410 if (printfuncs->start_job)
00411 return (printfuncs->start_job)(v, image);
00412 else
00413 return 1;
00414 }
00415
00416 int
00417 stp_end_job(const stp_vars_t *v, stp_image_t *image)
00418 {
00419 const stp_printfuncs_t *printfuncs =
00420 stpi_get_printfuncs(stp_get_printer(v));
00421 if (!stp_get_string_parameter(v, "JobMode") ||
00422 strcmp(stp_get_string_parameter(v, "JobMode"), "Page") == 0)
00423 return 1;
00424 if (printfuncs->end_job)
00425 return (printfuncs->end_job)(v, image);
00426 else
00427 return 1;
00428 }
00429
00430 static int
00431 verify_string_param(const stp_vars_t *v, const char *parameter,
00432 stp_parameter_t *desc, int quiet)
00433 {
00434 stp_parameter_verify_t answer = PARAMETER_OK;
00435 stp_dprintf(STP_DBG_VARS, v, " Verifying string %s\n", parameter);
00436 if (desc->is_mandatory ||
00437 stp_check_string_parameter(v, parameter, STP_PARAMETER_ACTIVE))
00438 {
00439 const char *checkval = stp_get_string_parameter(v, parameter);
00440 stp_string_list_t vptr = desc->bounds.str;
00441 size_t count = 0;
00442 int i;
00443 stp_dprintf(STP_DBG_VARS, v, " value %s\n",
00444 checkval ? checkval : "(null)");
00445 if (vptr)
00446 count = stp_string_list_count(vptr);
00447 answer = PARAMETER_BAD;
00448 if (checkval == NULL)
00449 {
00450 if (count == 0)
00451 answer = PARAMETER_OK;
00452 else
00453 {
00454 if (!quiet)
00455 stp_eprintf(v, _("Value must be set for %s\n"), parameter);
00456 answer = PARAMETER_BAD;
00457 }
00458 }
00459 else if (count > 0)
00460 {
00461 for (i = 0; i < count; i++)
00462 if (!strcmp(checkval, stp_string_list_param(vptr, i)->name))
00463 {
00464 answer = PARAMETER_OK;
00465 break;
00466 }
00467 if (!answer && !quiet)
00468 stp_eprintf(v, _("`%s' is not a valid %s\n"), checkval, parameter);
00469 }
00470 else if (strlen(checkval) == 0)
00471 answer = PARAMETER_OK;
00472 else if (!quiet)
00473 stp_eprintf(v, _("`%s' is not a valid %s\n"), checkval, parameter);
00474 }
00475 stp_parameter_description_destroy(desc);
00476 return answer;
00477 }
00478
00479 static int
00480 verify_double_param(const stp_vars_t *v, const char *parameter,
00481 stp_parameter_t *desc, int quiet)
00482 {
00483 stp_dprintf(STP_DBG_VARS, v, " Verifying double %s\n", parameter);
00484 if (desc->is_mandatory ||
00485 stp_check_float_parameter(v, parameter, STP_PARAMETER_ACTIVE))
00486 {
00487 double checkval = stp_get_float_parameter(v, parameter);
00488 if (checkval < desc->bounds.dbl.lower ||
00489 checkval > desc->bounds.dbl.upper)
00490 {
00491 if (!quiet)
00492 stp_eprintf(v, _("%s must be between %f and %f (is %f)\n"),
00493 parameter, desc->bounds.dbl.lower,
00494 desc->bounds.dbl.upper, checkval);
00495 return PARAMETER_BAD;
00496 }
00497 }
00498 return PARAMETER_OK;
00499 }
00500
00501 static int
00502 verify_int_param(const stp_vars_t *v, const char *parameter,
00503 stp_parameter_t *desc, int quiet)
00504 {
00505 stp_dprintf(STP_DBG_VARS, v, " Verifying int %s\n", parameter);
00506 if (desc->is_mandatory ||
00507 stp_check_int_parameter(v, parameter, STP_PARAMETER_ACTIVE))
00508 {
00509 int checkval = stp_get_int_parameter(v, parameter);
00510 if (checkval < desc->bounds.integer.lower ||
00511 checkval > desc->bounds.integer.upper)
00512 {
00513 if (!quiet)
00514 stp_eprintf(v, _("%s must be between %d and %d (is %d)\n"),
00515 parameter, desc->bounds.integer.lower,
00516 desc->bounds.integer.upper, checkval);
00517 stp_parameter_description_destroy(desc);
00518 return PARAMETER_BAD;
00519 }
00520 }
00521 stp_parameter_description_destroy(desc);
00522 return PARAMETER_OK;
00523 }
00524
00525 static int
00526 verify_curve_param(const stp_vars_t *v, const char *parameter,
00527 stp_parameter_t *desc, int quiet)
00528 {
00529 stp_parameter_verify_t answer = 1;
00530 stp_dprintf(STP_DBG_VARS, v, " Verifying curve %s\n", parameter);
00531 if (desc->bounds.curve &&
00532 (desc->is_mandatory ||
00533 stp_check_curve_parameter(v, parameter, STP_PARAMETER_ACTIVE)))
00534 {
00535 const stp_curve_t *checkval = stp_get_curve_parameter(v, parameter);
00536 if (checkval)
00537 {
00538 double u0, l0;
00539 double u1, l1;
00540 stp_curve_get_bounds(checkval, &l0, &u0);
00541 stp_curve_get_bounds(desc->bounds.curve, &l1, &u1);
00542 if (u0 > u1 || l0 < l1)
00543 {
00544 if (!quiet)
00545 stp_eprintf(v, _("%s bounds must be between %f and %f\n"),
00546 parameter, l1, u1);
00547 answer = PARAMETER_BAD;
00548 }
00549 if (stp_curve_get_wrap(checkval) !=
00550 stp_curve_get_wrap(desc->bounds.curve))
00551 {
00552 if (!quiet)
00553 stp_eprintf(v, _("%s wrap mode must be %s\n"),
00554 parameter,
00555 (stp_curve_get_wrap(desc->bounds.curve) ==
00556 STP_CURVE_WRAP_NONE) ?
00557 _("no wrap") : _("wrap around"));
00558 answer = PARAMETER_BAD;
00559 }
00560 }
00561 }
00562 stp_parameter_description_destroy(desc);
00563 return answer;
00564 }
00565
00566 stp_parameter_verify_t
00567 stp_verify_parameter(const stp_vars_t *v, const char *parameter,
00568 int quiet)
00569 {
00570 stp_parameter_t desc;
00571 quiet = 0;
00572 stp_describe_parameter(v, parameter, &desc);
00573 stp_dprintf(STP_DBG_VARS, v, " Verifying %s %d %d\n", parameter,
00574 desc.is_active, desc.read_only);
00575 if (!desc.is_active || desc.read_only)
00576 {
00577 stp_parameter_description_destroy(&desc);
00578 return PARAMETER_INACTIVE;
00579 }
00580 switch (desc.p_type)
00581 {
00582 case STP_PARAMETER_TYPE_STRING_LIST:
00583 return verify_string_param(v, parameter, &desc, quiet);
00584 case STP_PARAMETER_TYPE_DOUBLE:
00585 return verify_double_param(v, parameter, &desc, quiet);
00586 case STP_PARAMETER_TYPE_INT:
00587 return verify_int_param(v, parameter, &desc, quiet);
00588 case STP_PARAMETER_TYPE_CURVE:
00589 return verify_curve_param(v, parameter, &desc, quiet);
00590 case STP_PARAMETER_TYPE_RAW:
00591 case STP_PARAMETER_TYPE_FILE:
00592 stp_parameter_description_destroy(&desc);
00593 return PARAMETER_OK;
00594 case STP_PARAMETER_TYPE_BOOLEAN:
00595 stp_parameter_description_destroy(&desc);
00596 return PARAMETER_OK;
00597 default:
00598 if (!quiet)
00599 stp_eprintf(v, _("Unknown type parameter %s (%d)\n"),
00600 parameter, desc.p_type);
00601 stp_parameter_description_destroy(&desc);
00602 return 0;
00603 }
00604 }
00605
00606 #define CHECK_INT_RANGE(v, component, min, max) \
00607 do \
00608 { \
00609 if (stp_get_##component((v)) < (min) || stp_get_##component((v)) > (max)) \
00610 { \
00611 answer = 0; \
00612 stp_eprintf(v, _("%s out of range (value %d, min %d, max %d)\n"), \
00613 #component, stp_get_##component(v), min, max); \
00614 } \
00615 } while (0)
00616
00617 #define CHECK_INT_RANGE_INTERNAL(v, component, min, max) \
00618 do \
00619 { \
00620 if (stpi_get_##component((v)) < (min) || stpi_get_##component((v)) > (max)) \
00621 { \
00622 answer = 0; \
00623 stp_eprintf(v, _("%s out of range (value %d, min %d, max %d)\n"), \
00624 #component, stpi_get_##component(v), min, max); \
00625 } \
00626 } while (0)
00627
00628 typedef struct
00629 {
00630 char *data;
00631 size_t bytes;
00632 } errbuf_t;
00633
00634 static void
00635 fill_buffer_writefunc(void *priv, const char *buffer, size_t bytes)
00636 {
00637 errbuf_t *errbuf = (errbuf_t *) priv;
00638 if (errbuf->bytes == 0)
00639 errbuf->data = stp_malloc(bytes + 1);
00640 else
00641 errbuf->data = stp_realloc(errbuf->data, errbuf->bytes + bytes + 1);
00642 memcpy(errbuf->data + errbuf->bytes, buffer, bytes);
00643 errbuf->bytes += bytes;
00644 errbuf->data[errbuf->bytes] = '\0';
00645 }
00646
00647 int
00648 stp_verify_printer_params(stp_vars_t *v)
00649 {
00650 errbuf_t errbuf;
00651 stp_outfunc_t ofunc = stp_get_errfunc(v);
00652 void *odata = stp_get_errdata(v);
00653
00654 stp_parameter_list_t params;
00655 int nparams;
00656 int i;
00657 int answer = 1;
00658 int left, top, bottom, right;
00659 const char *pagesize = stp_get_string_parameter(v, "PageSize");
00660
00661 stp_set_errfunc((stp_vars_t *) v, fill_buffer_writefunc);
00662 stp_set_errdata((stp_vars_t *) v, &errbuf);
00663
00664 errbuf.data = NULL;
00665 errbuf.bytes = 0;
00666
00667 if (pagesize && strlen(pagesize) > 0)
00668 {
00669 if (stp_verify_parameter(v, "PageSize", 0) == 0)
00670 answer = 0;
00671 }
00672 else
00673 {
00674 int width, height, min_height, min_width;
00675 stp_get_size_limit(v, &width, &height, &min_width, &min_height);
00676 if (stp_get_page_height(v) <= min_height ||
00677 stp_get_page_height(v) > height ||
00678 stp_get_page_width(v) <= min_width || stp_get_page_width(v) > width)
00679 {
00680 answer = 0;
00681 stp_eprintf(v, _("Page size is not valid\n"));
00682 }
00683 stp_dprintf(STP_DBG_PAPER, v,
00684 "page size max %d %d min %d %d actual %d %d\n",
00685 width, height, min_width, min_height,
00686 stp_get_page_width(v), stp_get_page_height(v));
00687 }
00688
00689 stp_get_imageable_area(v, &left, &right, &bottom, &top);
00690
00691 stp_dprintf(STP_DBG_PAPER, v,
00692 "page left %d top %d right %d bottom %d\n",
00693 left, top, right, bottom);
00694 stp_dprintf(STP_DBG_PAPER, v,
00695 "requested left %d top %d width %d height %d\n",
00696 stp_get_left(v), stp_get_top(v),
00697 stp_get_width(v), stp_get_height(v));
00698
00699 if (stp_get_top(v) < top)
00700 {
00701 answer = 0;
00702 stp_eprintf(v, _("Top margin must not be less than %d\n"), top);
00703 }
00704
00705 if (stp_get_left(v) < left)
00706 {
00707 answer = 0;
00708 stp_eprintf(v, _("Left margin must not be less than %d\n"), left);
00709 }
00710
00711 if (stp_get_height(v) <= 0)
00712 {
00713 answer = 0;
00714 stp_eprintf(v, _("Height must be greater than zero\n"));
00715 }
00716
00717 if (stp_get_width(v) <= 0)
00718 {
00719 answer = 0;
00720 stp_eprintf(v, _("Width must be greater than zero\n"));
00721 }
00722
00723 if (stp_get_left(v) + stp_get_width(v) > right)
00724 {
00725 answer = 0;
00726 stp_eprintf(v, _("Image is too wide for the page: left margin is %d, width %d, right edge is %d\n"),
00727 stp_get_left(v), stp_get_width(v), right);
00728 }
00729
00730 if (stp_get_top(v) + stp_get_height(v) > bottom)
00731 {
00732 answer = 0;
00733 stp_eprintf(v, _("Image is too long for the page: top margin is %d, height %d, bottom edge is %d\n"),
00734 stp_get_left(v), stp_get_width(v), right);
00735 }
00736
00737 params = stp_get_parameter_list(v);
00738 nparams = stp_parameter_list_count(params);
00739 for (i = 0; i < nparams; i++)
00740 {
00741 const stp_parameter_t *param = stp_parameter_list_param(params, i);
00742 stp_dprintf(STP_DBG_VARS, v, "Checking %s %d %d\n", param->name,
00743 param->is_active, param->verify_this_parameter);
00744
00745 if (strcmp(param->name, "PageSize") != 0 &&
00746 param->is_active && param->verify_this_parameter &&
00747 stp_verify_parameter(v, param->name, 0) == 0)
00748 answer = 0;
00749 }
00750 stp_parameter_list_destroy(params);
00751 stp_set_errfunc((stp_vars_t *) v, ofunc);
00752 stp_set_errdata((stp_vars_t *) v, odata);
00753 stp_set_verified((stp_vars_t *) v, answer);
00754 if (errbuf.bytes > 0)
00755 {
00756 stp_eprintf(v, "%s", errbuf.data);
00757 stp_free(errbuf.data);
00758 }
00759 return answer;
00760 }
00761
00762
00763 typedef struct
00764 {
00765 const char *property;
00766 const char *parameter;
00767 } stpi_xml_prop_t;
00768
00769 static const stpi_xml_prop_t stpi_xml_props[] =
00770 {
00771 { "black", "BlackGamma" },
00772 { "cyan", "CyanGamma" },
00773 { "yellow", "YellowGamma" },
00774 { "magenta", "MagentaGamma" },
00775 { "brightness", "Brightness" },
00776 { "gamma", "Gamma" },
00777 { "density", "Density" },
00778 { "saturation", "Saturation" },
00779 { "blackdensity", "BlackDensity" },
00780 { "cyandensity", "CyanDensity" },
00781 { "yellowdensity", "YellowDensity" },
00782 { "magentadensity", "MagentaDensity" },
00783 { "gcrlower", "GCRLower" },
00784 { "gcrupper", "GCRupper" },
00785 { NULL, NULL }
00786 };
00787
00788 int
00789 stp_family_register(stp_list_t *family)
00790 {
00791 stp_list_item_t *printer_item;
00792 const stp_printer_t *printer;
00793
00794 if (printer_list == NULL)
00795 {
00796 stpi_init_printer_list();
00797 stp_deprintf
00798 (STP_DBG_PRINTERS,
00799 "stpi_family_register(): initialising printer_list...\n");
00800 }
00801
00802 if (family)
00803 {
00804 printer_item = stp_list_get_start(family);
00805
00806 while(printer_item)
00807 {
00808 printer = (const stp_printer_t *) stp_list_item_get_data(printer_item);
00809 if (!stp_list_get_item_by_name(printer_list,
00810 stp_get_driver(printer->printvars)))
00811 stp_list_item_create(printer_list, NULL, printer);
00812 printer_item = stp_list_item_next(printer_item);
00813 }
00814 }
00815
00816 return 0;
00817 }
00818
00819 int
00820 stp_family_unregister(stp_list_t *family)
00821 {
00822 stp_list_item_t *printer_item;
00823 stp_list_item_t *old_printer_item;
00824 const stp_printer_t *printer;
00825
00826 if (printer_list == NULL)
00827 {
00828 stpi_init_printer_list();
00829 stp_deprintf
00830 (STP_DBG_PRINTERS,
00831 "stpi_family_unregister(): initialising printer_list...\n");
00832 }
00833
00834 if (family)
00835 {
00836 printer_item = stp_list_get_start(family);
00837
00838 while(printer_item)
00839 {
00840 printer = (const stp_printer_t *) stp_list_item_get_data(printer_item);
00841 old_printer_item =
00842 stp_list_get_item_by_name(printer_list,
00843 stp_get_driver(printer->printvars));
00844
00845 if (old_printer_item)
00846 stp_list_item_destroy(printer_list, old_printer_item);
00847 printer_item = stp_list_item_next(printer_item);
00848 }
00849 }
00850 return 0;
00851 }
00852
00853
00854
00855
00856
00857 static stp_printer_t*
00858 stp_printer_create_from_xmltree(stp_mxml_node_t *printer,
00859 const char *family,
00860 const stp_printfuncs_t *printfuncs)
00861
00862 {
00863 stp_mxml_node_t *prop;
00864 const char *stmp;
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 stp_printer_t *outprinter;
00886 int
00887 driver = 0,
00888 long_name = 0,
00889 model = 0;
00890
00891 outprinter = stp_zalloc(sizeof(stp_printer_t));
00892 if (!outprinter)
00893 return NULL;
00894 outprinter->printvars = stp_vars_create();
00895 if (outprinter->printvars == NULL)
00896 {
00897 stp_free(outprinter);
00898 return NULL;
00899 }
00900
00901 stmp = stp_mxmlElementGetAttr(printer, "driver");
00902 stp_set_driver(outprinter->printvars, (const char *) stmp);
00903
00904 outprinter->long_name = stp_strdup(stp_mxmlElementGetAttr(printer, "name"));
00905 outprinter->manufacturer = stp_strdup(stp_mxmlElementGetAttr(printer, "manufacturer"));
00906 outprinter->family = stp_strdup((const char *) family);
00907
00908 if (stp_get_driver(outprinter->printvars))
00909 driver = 1;
00910 if (outprinter->long_name)
00911 long_name = 1;
00912
00913 outprinter->printfuncs = printfuncs;
00914
00915 prop = printer->child;
00916 while (prop)
00917 {
00918 if (prop->type == STP_MXML_ELEMENT)
00919 {
00920 const char *prop_name = prop->value.element.name;
00921 if (!strcmp(prop_name, "model"))
00922 {
00923 stmp = stp_mxmlElementGetAttr(prop, "value");
00924 if (stmp)
00925 {
00926 outprinter->model = stp_xmlstrtol(stmp);
00927 model = 1;
00928 }
00929 }
00930 else
00931 {
00932 const stpi_xml_prop_t *stp_prop = stpi_xml_props;
00933 while (stp_prop->property)
00934 {
00935 if (!strcmp(prop_name, stp_prop->property))
00936 {
00937 stmp = stp_mxmlElementGetAttr(prop, "value");
00938 if (stmp)
00939 {
00940 stp_set_float_parameter(outprinter->printvars,
00941 stp_prop->parameter,
00942 (float) stp_xmlstrtod(stmp));
00943 break;
00944 }
00945 }
00946 stp_prop++;
00947 }
00948 }
00949 }
00950 prop = prop->next;
00951 }
00952 if (driver && long_name && model && printfuncs)
00953 {
00954 if (stp_get_debug_level() & STP_DBG_XML)
00955 {
00956 stmp = stp_mxmlElementGetAttr(printer, "driver");
00957 stp_erprintf("stp_printer_create_from_xmltree: printer: %s\n", stmp);
00958 }
00959 outprinter->driver = stp_get_driver(outprinter->printvars);
00960 return outprinter;
00961 }
00962 stp_free(outprinter);
00963 return NULL;
00964 }
00965
00966
00967
00968
00969 static void
00970 stpi_xml_process_family(stp_mxml_node_t *family)
00971 {
00972 stp_list_t *family_module_list = NULL;
00973 stp_list_item_t *family_module_item;
00974 const char *family_name;
00975 stp_mxml_node_t *printer;
00976 stp_module_t *family_module_data;
00977 stp_family_t *family_data = NULL;
00978 int family_valid = 0;
00979 stp_printer_t *outprinter;
00980
00981 family_module_list = stp_module_get_class(STP_MODULE_CLASS_FAMILY);
00982 if (!family_module_list)
00983 return;
00984
00985 family_name = stp_mxmlElementGetAttr(family, "name");
00986 family_module_item = stp_list_get_start(family_module_list);
00987 while (family_module_item)
00988 {
00989 family_module_data = (stp_module_t *)
00990 stp_list_item_get_data(family_module_item);
00991 if (!strcmp(family_name, family_module_data->name))
00992 {
00993 stp_deprintf(STP_DBG_XML,
00994 "stpi_xml_process_family: family module: %s\n",
00995 family_module_data->name);
00996 family_data = family_module_data->syms;
00997 if (family_data->printer_list == NULL)
00998 family_data->printer_list = stp_list_create();
00999 family_valid = 1;
01000 }
01001 family_module_item = stp_list_item_next(family_module_item);
01002 }
01003
01004 printer = family->child;
01005 while (family_valid && printer)
01006 {
01007 if (printer->type == STP_MXML_ELEMENT)
01008 {
01009 const char *printer_name = printer->value.element.name;
01010 if (!strcmp(printer_name, "printer"))
01011 {
01012 outprinter =
01013 stp_printer_create_from_xmltree(printer, family_name,
01014 family_data->printfuncs);
01015 if (outprinter)
01016 stp_list_item_create(family_data->printer_list, NULL,
01017 outprinter);
01018 }
01019 }
01020 printer = printer->next;
01021 }
01022
01023 stp_list_destroy(family_module_list);
01024 return;
01025 }
01026
01027
01028
01029
01030 static int
01031 stpi_xml_process_printdef(stp_mxml_node_t *printdef, const char *file)
01032 {
01033 stp_mxml_node_t *family;
01034
01035 family = printdef->child;
01036 while (family)
01037 {
01038 if (family->type == STP_MXML_ELEMENT)
01039 {
01040 const char *family_name = family->value.element.name;
01041 if (!strcmp(family_name, "family"))
01042 {
01043 stpi_xml_process_family(family);
01044 }
01045 }
01046 family = family->next;
01047 }
01048 return 1;
01049 }
01050
01051 void
01052 stpi_init_printer(void)
01053 {
01054 stp_register_xml_parser("printdef", stpi_xml_process_printdef);
01055 stp_register_xml_preload("printers.xml");
01056 }