Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

src/main/printers.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: printers.c,v 1.70 2004/05/07 19:20:34 rleigh 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_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;              /* No way to verify this here */
00594     case STP_PARAMETER_TYPE_BOOLEAN:
00595       stp_parameter_description_destroy(&desc);
00596       return PARAMETER_OK;              /* Booleans always 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  * Parse the printer node, and return the generated printer.  Returns
00855  * NULL on failure.
00856  */
00857 static stp_printer_t*
00858 stp_printer_create_from_xmltree(stp_mxml_node_t *printer, /* The printer node */
00859                                 const char *family,       /* Family name */
00860                                 const stp_printfuncs_t *printfuncs)
00861                                                        /* Family printfuncs */
00862 {
00863   stp_mxml_node_t *prop;                                  /* Temporary node pointer */
00864   const char *stmp;                                    /* Temporary string */
00865  /* props[] (unused) is the correct tag sequence */
00866   /*  const char *props[] =
00867     {
00868       "model",
00869       "black",
00870       "cyan",
00871       "yellow",
00872       "magenta",
00873       "brightness",
00874       "gamma",
00875       "density",
00876       "saturation",
00877       "blackgamma",
00878       "cyangamma",
00879       "yellowgamma",
00880       "magentagamma",
00881       "gcrlower",
00882       "gcrupper",
00883       NULL
00884       };*/
00885   stp_printer_t *outprinter;                 /* Generated printer */
00886   int
00887     driver = 0,                                       /* Check driver */
00888     long_name = 0,                                    /* Check long_name */
00889     model = 0;                                        /* Check model */
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  * Parse the <family> node.
00968  */
00969 static void
00970 stpi_xml_process_family(stp_mxml_node_t *family)     /* The family node */
00971 {
00972   stp_list_t *family_module_list = NULL;      /* List of valid families */
00973   stp_list_item_t *family_module_item;        /* Current family */
00974   const char *family_name;                       /* Name of family */
00975   stp_mxml_node_t *printer;                         /* printer child node */
00976   stp_module_t *family_module_data;           /* Family module data */
00977   stp_family_t *family_data = NULL;  /* Family data */
00978   int family_valid = 0;                       /* Is family valid? */
00979   stp_printer_t *outprinter;         /* Generated printer */
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  * Parse the <printdef> node.
01029  */
01030 static int
01031 stpi_xml_process_printdef(stp_mxml_node_t *printdef, const char *file) /* The printdef node */
01032 {
01033   stp_mxml_node_t *family;                          /* Family child node */
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 }

Generated on Wed May 12 20:21:33 2004 for libgimpprint API Reference by doxygen1.2.17