Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

src/main/printers.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: printers.c,v 1.73 2004/08/19 03:24:36 rlk Exp $"
00003  *
00004  *   Print plug-in driver utility functions for the GIMP.
00005  *
00006  *   Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
00007  *      Robert Krawitz (rlk@alum.mit.edu)
00008  *
00009  *   This program is free software; you can redistribute it and/or modify it
00010  *   under the terms of the GNU General Public License as published by the Free
00011  *   Software Foundation; either version 2 of the License, or (at your option)
00012  *   any later version.
00013  *
00014  *   This program is distributed in the hope that it will be useful, but
00015  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00016  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017  *   for more details.
00018  *
00019  *   You should have received a copy of the GNU General Public License
00020  *   along with this program; if not, write to the Free Software
00021  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00022  */
00023 
00024 /*
00025  * This file must include only standard C header files.  The core code must
00026  * compile on generic platforms that don't support glib, gimp, gtk, etc.
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;        /* Long name for UI */
00055   char       *family;           /* Printer family */
00056   char       *manufacturer;     /* Printer manufacturer */
00057   int        model;             /* Model number */
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   /* stp_list_set_sortfunc(printer_list, stpi_printer_sortfunc); */
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   /* There should be no need to ever know the index! */
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_DIMENSION:
00291               stp_set_dimension_parameter(v, p->name, desc.deflt.dimension);
00292               stp_set_dimension_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00293               break;
00294             case STP_PARAMETER_TYPE_BOOLEAN:
00295               stp_set_boolean_parameter(v, p->name, desc.deflt.boolean);
00296               stp_set_boolean_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00297               break;
00298             case STP_PARAMETER_TYPE_CURVE:
00299               stp_set_curve_parameter(v, p->name, desc.deflt.curve);
00300               stp_set_curve_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00301               break;
00302             case STP_PARAMETER_TYPE_ARRAY:
00303               stp_set_array_parameter(v, p->name, desc.deflt.array);
00304               stp_set_array_parameter_active(v, p->name, STP_PARAMETER_ACTIVE);
00305               break;
00306             default:
00307               break;
00308             }
00309           stp_parameter_description_destroy(&desc);
00310         }
00311     }
00312   stp_parameter_list_destroy(params);
00313 }
00314 
00315 void
00316 stp_set_printer_defaults(stp_vars_t *v, const stp_printer_t *printer)
00317 {
00318   stp_set_driver(v, stp_printer_get_driver(printer));
00319   set_printer_defaults(v, 0);
00320 }
00321 
00322 void
00323 stp_initialize_printer_defaults(void)
00324 {
00325   stp_list_item_t *printer_item;
00326   if (printer_list == NULL)
00327     {
00328       stpi_init_printer_list();
00329       stp_deprintf
00330         (STP_DBG_PRINTERS,
00331          "stpi_family_register(): initialising printer_list...\n");
00332     }
00333   printer_item = stp_list_get_start(printer_list);
00334   while (printer_item)
00335     {
00336       set_printer_defaults
00337         (((stp_printer_t *)(stp_list_item_get_data(printer_item)))->printvars, 1);
00338       printer_item = stp_list_item_next(printer_item);
00339     }
00340 }
00341 
00342 void
00343 stp_get_media_size(const stp_vars_t *v, int *width, int *height)
00344 {
00345   const stp_printfuncs_t *printfuncs =
00346     stpi_get_printfuncs(stp_get_printer(v));
00347   (printfuncs->media_size)(v, width, height);
00348 }
00349 
00350 void
00351 stp_get_imageable_area(const stp_vars_t *v,
00352                        int *left, int *right, int *bottom, int *top)
00353 {
00354   const stp_printfuncs_t *printfuncs =
00355     stpi_get_printfuncs(stp_get_printer(v));
00356   (printfuncs->imageable_area)(v, left, right, bottom, top);
00357 }
00358 
00359 void
00360 stp_get_size_limit(const stp_vars_t *v, int *max_width, int *max_height,
00361                    int *min_width, int *min_height)
00362 {
00363   const stp_printfuncs_t *printfuncs =
00364     stpi_get_printfuncs(stp_get_printer(v));
00365   (printfuncs->limit)(v, max_width, max_height, min_width,min_height);
00366 }
00367 
00368 void
00369 stp_describe_resolution(const stp_vars_t *v, int *x, int *y)
00370 {
00371   const stp_printfuncs_t *printfuncs =
00372     stpi_get_printfuncs(stp_get_printer(v));
00373   (printfuncs->describe_resolution)(v, x, y);
00374 }
00375 
00376 const char *
00377 stp_describe_output(const stp_vars_t *v)
00378 {
00379   const stp_printfuncs_t *printfuncs =
00380     stpi_get_printfuncs(stp_get_printer(v));
00381   return (printfuncs->describe_output)(v);
00382 }
00383 
00384 int
00385 stp_verify(stp_vars_t *v)
00386 {
00387   const stp_printfuncs_t *printfuncs =
00388     stpi_get_printfuncs(stp_get_printer(v));
00389   stp_vars_t *nv = stp_vars_create_copy(v);
00390   int status;
00391   stp_prune_inactive_options(nv);
00392   status = (printfuncs->verify)(nv);
00393   stp_set_verified(v, stp_get_verified(nv));
00394   stp_vars_destroy(nv);
00395   return status;
00396 }
00397 
00398 int
00399 stp_print(const stp_vars_t *v, stp_image_t *image)
00400 {
00401   const stp_printfuncs_t *printfuncs =
00402     stpi_get_printfuncs(stp_get_printer(v));
00403   return (printfuncs->print)(v, image);
00404 }
00405 
00406 int
00407 stp_start_job(const stp_vars_t *v, stp_image_t *image)
00408 {
00409   const stp_printfuncs_t *printfuncs =
00410     stpi_get_printfuncs(stp_get_printer(v));
00411   if (!stp_get_string_parameter(v, "JobMode") ||
00412       strcmp(stp_get_string_parameter(v, "JobMode"), "Page") == 0)
00413     return 1;
00414   if (printfuncs->start_job)
00415     return (printfuncs->start_job)(v, image);
00416   else
00417     return 1;
00418 }
00419 
00420 int
00421 stp_end_job(const stp_vars_t *v, stp_image_t *image)
00422 {
00423   const stp_printfuncs_t *printfuncs =
00424     stpi_get_printfuncs(stp_get_printer(v));
00425   if (!stp_get_string_parameter(v, "JobMode") ||
00426       strcmp(stp_get_string_parameter(v, "JobMode"), "Page") == 0)
00427     return 1;
00428   if (printfuncs->end_job)
00429     return (printfuncs->end_job)(v, image);
00430   else
00431     return 1;
00432 }
00433 
00434 static int
00435 verify_string_param(const stp_vars_t *v, const char *parameter,
00436                     stp_parameter_t *desc, int quiet)
00437 {
00438   stp_parameter_verify_t answer = PARAMETER_OK;
00439   stp_dprintf(STP_DBG_VARS, v, "    Verifying string %s\n", parameter);
00440   if (desc->is_mandatory ||
00441       stp_check_string_parameter(v, parameter, STP_PARAMETER_ACTIVE))
00442     {
00443       const char *checkval = stp_get_string_parameter(v, parameter);
00444       stp_string_list_t *vptr = desc->bounds.str;
00445       size_t count = 0;
00446       int i;
00447       stp_dprintf(STP_DBG_VARS, v, "     value %s\n",
00448                   checkval ? checkval : "(null)");
00449       if (vptr)
00450         count = stp_string_list_count(vptr);
00451       answer = PARAMETER_BAD;
00452       if (checkval == NULL)
00453         {
00454           if (count == 0)
00455             answer = PARAMETER_OK;
00456           else
00457             {
00458               if (!quiet)
00459                 stp_eprintf(v, _("Value must be set for %s\n"), parameter);
00460               answer = PARAMETER_BAD;
00461             }
00462         }
00463       else if (count > 0)
00464         {
00465           for (i = 0; i < count; i++)
00466             if (!strcmp(checkval, stp_string_list_param(vptr, i)->name))
00467               {
00468                 answer = PARAMETER_OK;
00469                 break;
00470               }
00471           if (!answer && !quiet)
00472             stp_eprintf(v, _("`%s' is not a valid %s\n"), checkval, parameter);
00473         }
00474       else if (strlen(checkval) == 0)
00475         answer = PARAMETER_OK;
00476       else if (!quiet)
00477         stp_eprintf(v, _("`%s' is not a valid %s\n"), checkval, parameter);
00478     }
00479   stp_parameter_description_destroy(desc);
00480   return answer;
00481 }
00482 
00483 static int
00484 verify_double_param(const stp_vars_t *v, const char *parameter,
00485                     stp_parameter_t *desc, int quiet)
00486 {
00487   stp_dprintf(STP_DBG_VARS, v, "    Verifying double %s\n", parameter);
00488   if (desc->is_mandatory ||
00489       stp_check_float_parameter(v, parameter, STP_PARAMETER_ACTIVE))
00490     {
00491       double checkval = stp_get_float_parameter(v, parameter);
00492       if (checkval < desc->bounds.dbl.lower ||
00493           checkval > desc->bounds.dbl.upper)
00494         {
00495           if (!quiet)
00496             stp_eprintf(v, _("%s must be between %f and %f (is %f)\n"),
00497                         parameter, desc->bounds.dbl.lower,
00498                         desc->bounds.dbl.upper, checkval);
00499           return PARAMETER_BAD;
00500         }
00501     }
00502   return PARAMETER_OK;
00503 }
00504 
00505 static int
00506 verify_int_param(const stp_vars_t *v, const char *parameter,
00507                  stp_parameter_t *desc, int quiet)
00508 {
00509   stp_dprintf(STP_DBG_VARS, v, "    Verifying int %s\n", parameter);
00510   if (desc->is_mandatory ||
00511       stp_check_int_parameter(v, parameter, STP_PARAMETER_ACTIVE))
00512     {
00513       int checkval = stp_get_int_parameter(v, parameter);
00514       if (checkval < desc->bounds.integer.lower ||
00515           checkval > desc->bounds.integer.upper)
00516         {
00517           if (!quiet)
00518             stp_eprintf(v, _("%s must be between %d and %d (is %d)\n"),
00519                         parameter, desc->bounds.integer.lower,
00520                         desc->bounds.integer.upper, checkval);
00521           stp_parameter_description_destroy(desc);
00522           return PARAMETER_BAD;
00523         }
00524     }
00525   stp_parameter_description_destroy(desc);
00526   return PARAMETER_OK;
00527 }
00528 
00529 static int
00530 verify_dimension_param(const stp_vars_t *v, const char *parameter,
00531                  stp_parameter_t *desc, int quiet)
00532 {
00533   stp_dprintf(STP_DBG_VARS, v, "    Verifying dimension %s\n", parameter);
00534   if (desc->is_mandatory ||
00535       stp_check_dimension_parameter(v, parameter, STP_PARAMETER_ACTIVE))
00536     {
00537       int checkval = stp_get_dimension_parameter(v, parameter);
00538       if (checkval < desc->bounds.dimension.lower ||
00539           checkval > desc->bounds.dimension.upper)
00540         {
00541           if (!quiet)
00542             stp_eprintf(v, _("%s must be between %d and %d (is %d)\n"),
00543                         parameter, desc->bounds.dimension.lower,
00544                         desc->bounds.dimension.upper, checkval);
00545           stp_parameter_description_destroy(desc);
00546           return PARAMETER_BAD;
00547         }
00548     }
00549   stp_parameter_description_destroy(desc);
00550   return PARAMETER_OK;
00551 }
00552 
00553 static int
00554 verify_curve_param(const stp_vars_t *v, const char *parameter,
00555                    stp_parameter_t *desc, int quiet)
00556 {
00557   stp_parameter_verify_t answer = 1;
00558   stp_dprintf(STP_DBG_VARS, v, "    Verifying curve %s\n", parameter);
00559   if (desc->bounds.curve &&
00560       (desc->is_mandatory ||
00561        stp_check_curve_parameter(v, parameter, STP_PARAMETER_ACTIVE)))
00562     {
00563       const stp_curve_t *checkval = stp_get_curve_parameter(v, parameter);
00564       if (checkval)
00565         {
00566           double u0, l0;
00567           double u1, l1;
00568           stp_curve_get_bounds(checkval, &l0, &u0);
00569           stp_curve_get_bounds(desc->bounds.curve, &l1, &u1);
00570           if (u0 > u1 || l0 < l1)
00571             {
00572               if (!quiet)
00573                 stp_eprintf(v, _("%s bounds must be between %f and %f\n"),
00574                             parameter, l1, u1);
00575               answer = PARAMETER_BAD;
00576             }
00577           if (stp_curve_get_wrap(checkval) !=
00578               stp_curve_get_wrap(desc->bounds.curve))
00579             {
00580               if (!quiet)
00581                 stp_eprintf(v, _("%s wrap mode must be %s\n"),
00582                             parameter,
00583                             (stp_curve_get_wrap(desc->bounds.curve) ==
00584                              STP_CURVE_WRAP_NONE) ?
00585                             _("no wrap") : _("wrap around"));
00586               answer = PARAMETER_BAD;
00587             }
00588         }
00589     }
00590   stp_parameter_description_destroy(desc);
00591   return answer;
00592 }
00593 
00594 stp_parameter_verify_t
00595 stp_verify_parameter(const stp_vars_t *v, const char *parameter,
00596                      int quiet)
00597 {
00598   stp_parameter_t desc;
00599   quiet = 0;
00600   stp_describe_parameter(v, parameter, &desc);
00601   stp_dprintf(STP_DBG_VARS, v, "  Verifying %s %d %d\n", parameter,
00602               desc.is_active, desc.read_only);
00603   if (!desc.is_active || desc.read_only)
00604     {
00605       stp_parameter_description_destroy(&desc);
00606       return PARAMETER_INACTIVE;
00607     }
00608   switch (desc.p_type)
00609     {
00610     case STP_PARAMETER_TYPE_STRING_LIST:
00611       return verify_string_param(v, parameter, &desc, quiet);
00612     case STP_PARAMETER_TYPE_DOUBLE:
00613       return verify_double_param(v, parameter, &desc, quiet);
00614     case STP_PARAMETER_TYPE_INT:
00615       return verify_int_param(v, parameter, &desc, quiet);
00616     case STP_PARAMETER_TYPE_DIMENSION:
00617       return verify_dimension_param(v, parameter, &desc, quiet);
00618     case STP_PARAMETER_TYPE_CURVE:
00619       return verify_curve_param(v, parameter, &desc, quiet);
00620     case STP_PARAMETER_TYPE_RAW:
00621     case STP_PARAMETER_TYPE_FILE:
00622       stp_parameter_description_destroy(&desc);
00623       return PARAMETER_OK;              /* No way to verify this here */
00624     case STP_PARAMETER_TYPE_BOOLEAN:
00625       stp_parameter_description_destroy(&desc);
00626       return PARAMETER_OK;              /* Booleans always OK */
00627     default:
00628       if (!quiet)
00629         stp_eprintf(v, _("Unknown type parameter %s (%d)\n"),
00630                     parameter, desc.p_type);
00631       stp_parameter_description_destroy(&desc);
00632       return 0;
00633     }
00634 }
00635 
00636 #define CHECK_INT_RANGE(v, component, min, max)                             \
00637 do                                                                          \
00638 {                                                                           \
00639   if (stp_get_##component((v)) < (min) || stp_get_##component((v)) > (max)) \
00640     {                                                                       \
00641       answer = 0;                                                           \
00642       stp_eprintf(v, _("%s out of range (value %d, min %d, max %d)\n"),     \
00643                   #component, stp_get_##component(v), min, max);            \
00644     }                                                                       \
00645 } while (0)
00646 
00647 #define CHECK_INT_RANGE_INTERNAL(v, component, min, max)                      \
00648 do                                                                            \
00649 {                                                                             \
00650   if (stpi_get_##component((v)) < (min) || stpi_get_##component((v)) > (max)) \
00651     {                                                                         \
00652       answer = 0;                                                             \
00653       stp_eprintf(v, _("%s out of range (value %d, min %d, max %d)\n"),       \
00654                   #component, stpi_get_##component(v), min, max);             \
00655     }                                                                         \
00656 } while (0)
00657 
00658 typedef struct
00659 {
00660   char *data;
00661   size_t bytes;
00662 } errbuf_t;
00663 
00664 static void
00665 fill_buffer_writefunc(void *priv, const char *buffer, size_t bytes)
00666 {
00667   errbuf_t *errbuf = (errbuf_t *) priv;
00668   if (errbuf->bytes == 0)
00669     errbuf->data = stp_malloc(bytes + 1);
00670   else
00671     errbuf->data = stp_realloc(errbuf->data, errbuf->bytes + bytes + 1);
00672   memcpy(errbuf->data + errbuf->bytes, buffer, bytes);
00673   errbuf->bytes += bytes;
00674   errbuf->data[errbuf->bytes] = '\0';
00675 }
00676 
00677 int
00678 stp_verify_printer_params(stp_vars_t *v)
00679 {
00680   errbuf_t errbuf;
00681   stp_outfunc_t ofunc = stp_get_errfunc(v);
00682   void *odata = stp_get_errdata(v);
00683 
00684   stp_parameter_list_t params;
00685   int nparams;
00686   int i;
00687   int answer = 1;
00688   int left, top, bottom, right;
00689   const char *pagesize = stp_get_string_parameter(v, "PageSize");
00690 
00691   stp_set_errfunc((stp_vars_t *) v, fill_buffer_writefunc);
00692   stp_set_errdata((stp_vars_t *) v, &errbuf);
00693 
00694   errbuf.data = NULL;
00695   errbuf.bytes = 0;
00696 
00697   if (pagesize && strlen(pagesize) > 0)
00698     {
00699       if (stp_verify_parameter(v, "PageSize", 0) == 0)
00700         answer = 0;
00701     }
00702   else
00703     {
00704       int width, height, min_height, min_width;
00705       stp_get_size_limit(v, &width, &height, &min_width, &min_height);
00706       if (stp_get_page_height(v) <= min_height ||
00707           stp_get_page_height(v) > height ||
00708           stp_get_page_width(v) <= min_width || stp_get_page_width(v) > width)
00709         {
00710           answer = 0;
00711           stp_eprintf(v, _("Page size is not valid\n"));
00712         }
00713       stp_dprintf(STP_DBG_PAPER, v,
00714                   "page size max %d %d min %d %d actual %d %d\n",
00715                   width, height, min_width, min_height,
00716                   stp_get_page_width(v), stp_get_page_height(v));
00717     }
00718 
00719   stp_get_imageable_area(v, &left, &right, &bottom, &top);
00720 
00721   stp_dprintf(STP_DBG_PAPER, v,
00722               "page      left %d top %d right %d bottom %d\n",
00723               left, top, right, bottom);
00724   stp_dprintf(STP_DBG_PAPER, v,
00725               "requested left %d top %d width %d height %d\n",
00726               stp_get_left(v), stp_get_top(v),
00727               stp_get_width(v), stp_get_height(v));
00728 
00729   if (stp_get_top(v) < top)
00730     {
00731       answer = 0;
00732       stp_eprintf(v, _("Top margin must not be less than %d\n"), top);
00733     }
00734 
00735   if (stp_get_left(v) < left)
00736     {
00737       answer = 0;
00738       stp_eprintf(v, _("Left margin must not be less than %d\n"), left);
00739     }
00740 
00741   if (stp_get_height(v) <= 0)
00742     {
00743       answer = 0;
00744       stp_eprintf(v, _("Height must be greater than zero\n"));
00745     }
00746 
00747   if (stp_get_width(v) <= 0)
00748     {
00749       answer = 0;
00750       stp_eprintf(v, _("Width must be greater than zero\n"));
00751     }
00752 
00753   if (stp_get_left(v) + stp_get_width(v) > right)
00754     {
00755       answer = 0;
00756       stp_eprintf(v, _("Image is too wide for the page: left margin is %d, width %d, right edge is %d\n"),
00757                   stp_get_left(v), stp_get_width(v), right);
00758     }
00759 
00760   if (stp_get_top(v) + stp_get_height(v) > bottom)
00761     {
00762       answer = 0;
00763       stp_eprintf(v, _("Image is too long for the page: top margin is %d, height %d, bottom edge is %d\n"),
00764                   stp_get_left(v), stp_get_width(v), right);
00765     }
00766 
00767   params = stp_get_parameter_list(v);
00768   nparams = stp_parameter_list_count(params);
00769   for (i = 0; i < nparams; i++)
00770     {
00771       const stp_parameter_t *param = stp_parameter_list_param(params, i);
00772       stp_dprintf(STP_DBG_VARS, v, "Checking %s %d %d\n", param->name,
00773                   param->is_active, param->verify_this_parameter);
00774 
00775       if (strcmp(param->name, "PageSize") != 0 &&
00776           param->is_active && param->verify_this_parameter &&
00777           stp_verify_parameter(v, param->name, 0) == 0)
00778         answer = 0;
00779     }
00780   stp_parameter_list_destroy(params);
00781   stp_set_errfunc((stp_vars_t *) v, ofunc);
00782   stp_set_errdata((stp_vars_t *) v, odata);
00783   stp_set_verified((stp_vars_t *) v, answer);
00784   if (errbuf.bytes > 0)
00785     {
00786       stp_eprintf(v, "%s", errbuf.data);
00787       stp_free(errbuf.data);
00788     }
00789   return answer;
00790 }
00791 
00792 int
00793 stp_family_register(stp_list_t *family)
00794 {
00795   stp_list_item_t *printer_item;
00796   const stp_printer_t *printer;
00797 
00798   if (printer_list == NULL)
00799     {
00800       stpi_init_printer_list();
00801       stp_deprintf
00802         (STP_DBG_PRINTERS,
00803          "stpi_family_register(): initialising printer_list...\n");
00804     }
00805 
00806   if (family)
00807     {
00808       printer_item = stp_list_get_start(family);
00809 
00810       while(printer_item)
00811         {
00812           printer = (const stp_printer_t *) stp_list_item_get_data(printer_item);
00813           if (!stp_list_get_item_by_name(printer_list,
00814                                           stp_get_driver(printer->printvars)))
00815             stp_list_item_create(printer_list, NULL, printer);
00816           printer_item = stp_list_item_next(printer_item);
00817         }
00818     }
00819 
00820   return 0;
00821 }
00822 
00823 int
00824 stp_family_unregister(stp_list_t *family)
00825 {
00826   stp_list_item_t *printer_item;
00827   stp_list_item_t *old_printer_item;
00828   const stp_printer_t *printer;
00829 
00830   if (printer_list == NULL)
00831     {
00832       stpi_init_printer_list();
00833       stp_deprintf
00834         (STP_DBG_PRINTERS,
00835          "stpi_family_unregister(): initialising printer_list...\n");
00836     }
00837 
00838   if (family)
00839     {
00840       printer_item = stp_list_get_start(family);
00841 
00842       while(printer_item)
00843         {
00844           printer = (const stp_printer_t *) stp_list_item_get_data(printer_item);
00845           old_printer_item =
00846             stp_list_get_item_by_name(printer_list,
00847                                       stp_get_driver(printer->printvars));
00848 
00849           if (old_printer_item)
00850             stp_list_item_destroy(printer_list, old_printer_item);
00851           printer_item = stp_list_item_next(printer_item);
00852         }
00853     }
00854   return 0;
00855 }
00856 
00857 /*
00858  * Parse the printer node, and return the generated printer.  Returns
00859  * NULL on failure.
00860  */
00861 static stp_printer_t*
00862 stp_printer_create_from_xmltree(stp_mxml_node_t *printer, /* The printer node */
00863                                 const char *family,       /* Family name */
00864                                 const stp_printfuncs_t *printfuncs)
00865                                                        /* Family printfuncs */
00866 {
00867   stp_mxml_node_t *prop;                                  /* Temporary node pointer */
00868   const char *stmp;                                    /* Temporary string */
00869   stp_printer_t *outprinter;                 /* Generated printer */
00870   int
00871     driver = 0,                                       /* Check driver */
00872     long_name = 0;
00873 
00874   outprinter = stp_zalloc(sizeof(stp_printer_t));
00875   if (!outprinter)
00876     return NULL;
00877   outprinter->printvars = stp_vars_create();
00878   if (outprinter->printvars == NULL)
00879     {
00880       stp_free(outprinter);
00881       return NULL;
00882     }
00883 
00884   stmp = stp_mxmlElementGetAttr(printer, "driver");
00885   stp_set_driver(outprinter->printvars, (const char *) stmp);
00886 
00887   outprinter->long_name = stp_strdup(stp_mxmlElementGetAttr(printer, "name"));
00888   outprinter->manufacturer = stp_strdup(stp_mxmlElementGetAttr(printer, "manufacturer"));
00889   outprinter->model = stp_xmlstrtol(stp_mxmlElementGetAttr(printer, "model"));
00890   outprinter->family = stp_strdup((const char *) family);
00891 
00892   if (stp_get_driver(outprinter->printvars))
00893     driver = 1;
00894   if (outprinter->long_name)
00895     long_name = 1;
00896 
00897   outprinter->printfuncs = printfuncs;
00898 
00899   prop = printer->child;
00900   while (prop)
00901     {
00902       if (prop->type == STP_MXML_ELEMENT)
00903         {
00904           const char *prop_name = prop->value.element.name;
00905           if (!strcmp(prop_name, "parameter"))
00906             {
00907               const char *p_type = stp_mxmlElementGetAttr(prop, "type");
00908               const char *p_name = stp_mxmlElementGetAttr(prop, "name");
00909               stp_mxml_node_t *child = prop->child;
00910               if (!p_type || !p_name)
00911                 stp_erprintf("Bad property on driver %s\n", outprinter->driver);
00912               else if (strcmp(p_type, "float") == 0)
00913                 {
00914                   if (child->type == STP_MXML_TEXT)
00915                     stp_set_float_parameter
00916                       (outprinter->printvars, p_name,
00917                        stp_xmlstrtod(child->value.text.string));
00918                 }
00919               else if (strcmp(p_type, "integer") == 0)
00920                 {
00921                   if (child->type == STP_MXML_TEXT)
00922                     stp_set_int_parameter
00923                       (outprinter->printvars, p_name,
00924                        (int) stp_xmlstrtol(child->value.text.string));
00925                 }
00926               else if (strcmp(p_type, "boolean") == 0)
00927                 {
00928                   if (child->type == STP_MXML_TEXT)
00929                     stp_set_boolean_parameter
00930                       (outprinter->printvars, p_name,
00931                        (int) stp_xmlstrtol(child->value.text.string));
00932                 }
00933               else if (strcmp(p_type, "string") == 0)
00934                 {
00935                   if (child->type == STP_MXML_TEXT)
00936                     stp_set_string_parameter
00937                       (outprinter->printvars, p_name, child->value.text.string);
00938                 }
00939               else if (strcmp(p_type, "curve") == 0)
00940                 {
00941                   stp_curve_t *curve = stp_curve_create_from_xmltree(child);
00942                   if (curve)
00943                     {
00944                       stp_set_curve_parameter(outprinter->printvars,
00945                                               p_name, curve);
00946                       stp_curve_destroy(curve);
00947                     }
00948                 }
00949               else if (strcmp(p_type, "array") == 0)
00950                 {
00951                   stp_array_t *array = stp_array_create_from_xmltree(child);
00952                   if (array)
00953                     {
00954                       stp_set_array_parameter(outprinter->printvars,
00955                                               p_name, array);
00956                       stp_array_destroy(array);
00957                     }
00958                 }
00959               else
00960                 {
00961                   stp_erprintf("Bad property %s type %s on driver %s\n",
00962                                p_name, p_type, outprinter->driver);
00963                   continue;
00964                 }
00965             }
00966         }
00967       prop = prop->next;
00968     }
00969   if (driver && long_name && printfuncs)
00970     {
00971       if (stp_get_debug_level() & STP_DBG_XML)
00972         {
00973           stmp = stp_mxmlElementGetAttr(printer, "driver");
00974           stp_erprintf("stp_printer_create_from_xmltree: printer: %s\n", stmp);
00975         }
00976       outprinter->driver = stp_get_driver(outprinter->printvars);
00977       return outprinter;
00978     }
00979   stp_free(outprinter);
00980   return NULL;
00981 }
00982 
00983 /*
00984  * Parse the <family> node.
00985  */
00986 static void
00987 stpi_xml_process_family(stp_mxml_node_t *family)     /* The family node */
00988 {
00989   stp_list_t *family_module_list = NULL;      /* List of valid families */
00990   stp_list_item_t *family_module_item;        /* Current family */
00991   const char *family_name;                       /* Name of family */
00992   stp_mxml_node_t *printer;                         /* printer child node */
00993   stp_module_t *family_module_data;           /* Family module data */
00994   stp_family_t *family_data = NULL;  /* Family data */
00995   int family_valid = 0;                       /* Is family valid? */
00996   stp_printer_t *outprinter;         /* Generated printer */
00997 
00998   family_module_list = stp_module_get_class(STP_MODULE_CLASS_FAMILY);
00999   if (!family_module_list)
01000     return;
01001 
01002   family_name = stp_mxmlElementGetAttr(family, "name");
01003   family_module_item = stp_list_get_start(family_module_list);
01004   while (family_module_item)
01005     {
01006       family_module_data = (stp_module_t *)
01007         stp_list_item_get_data(family_module_item);
01008       if (!strcmp(family_name, family_module_data->name))
01009         {
01010           stp_deprintf(STP_DBG_XML,
01011                        "stpi_xml_process_family: family module: %s\n",
01012                        family_module_data->name);
01013           family_data = family_module_data->syms;
01014           if (family_data->printer_list == NULL)
01015             family_data->printer_list = stp_list_create();
01016           family_valid = 1;
01017         }
01018       family_module_item = stp_list_item_next(family_module_item);
01019     }
01020 
01021   printer = family->child;
01022   while (family_valid && printer)
01023     {
01024       if (printer->type == STP_MXML_ELEMENT)
01025         {
01026           const char *printer_name = printer->value.element.name;
01027           if (!strcmp(printer_name, "printer"))
01028             {
01029               outprinter =
01030                 stp_printer_create_from_xmltree(printer, family_name,
01031                                                 family_data->printfuncs);
01032               if (outprinter)
01033                 stp_list_item_create(family_data->printer_list, NULL,
01034                                       outprinter);
01035             }
01036         }
01037       printer = printer->next;
01038     }
01039 
01040   stp_list_destroy(family_module_list);
01041   return;
01042 }
01043 
01044 /*
01045  * Parse the <printdef> node.
01046  */
01047 static int
01048 stpi_xml_process_printdef(stp_mxml_node_t *printdef, const char *file) /* The printdef node */
01049 {
01050   stp_mxml_node_t *family;                          /* Family child node */
01051 
01052   family = printdef->child;
01053   while (family)
01054     {
01055       if (family->type == STP_MXML_ELEMENT)
01056         {
01057           const char *family_name = family->value.element.name;
01058           if (!strcmp(family_name, "family"))
01059             {
01060               stpi_xml_process_family(family);
01061             }
01062         }
01063       family = family->next;
01064     }
01065   return 1;
01066 }
01067 
01068 void
01069 stpi_init_printer(void)
01070 {
01071   stp_register_xml_parser("printdef", stpi_xml_process_printdef);
01072   stp_register_xml_preload("printers.xml");
01073 }

Generated on Wed Aug 25 07:56:15 2004 for libgimpprint API Reference by doxygen 1.3.6