libgimpprint API Reference: src/main/print-lexmark.c Source File

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

# src/main/print-lexmark.c

Go to the documentation of this file.

    00001 /*
    00002  * "$Id: print-lexmark_8c-source.html,v 1.1.1.2 2004/12/22 23:49:08 jlovell Exp $"
    00003  *
    00004  *   Print plug-in Lexmark driver for the GIMP.
    00005  *
    00006  *   Copyright 2000 Richard Wisenoecker (richard.wisenoecker@gmx.at) and
    00007  *      Alwin Stolk (p.a.stolk@tmx.nl)
    00008  *
    00009  *   The plug-in is based on the code of the CANON BJL plugin for the GIMP
    00010  *   of Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu).
    00011  *
    00012  *
    00013  *   This program is free software; you can redistribute it and/or modify it
    00014  *   under the terms of the GNU General Public License as published by the Free
    00015  *   Software Foundation; either version 2 of the License, or (at your option)
    00016  *   any later version.
    00017  *
    00018  *   This program is distributed in the hope that it will be useful, but
    00019  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    00020  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    00021  *   for more details.
    00022  *
    00023  *   You should have received a copy of the GNU General Public License
    00024  *   along with this program; if not, write to the Free Software
    00025  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    00026  */
    00027
    00028 /*
    00029  * This file must include only standard C header files.  The core code must
    00030  * compile on generic platforms that don't support glib, gimp, gtk, etc.
    00031  */
    00032
    00033 /*
    00034  * !!! IMPORTANT !!!  Some short information: Border and page offsets
    00035  * are defined in 1/72 DPI. This mean, that the parameter defined at
    00036  * lexmark_cap_t which defines positions are in 1/72 DPI. At
    00037  * lexmark_print the unit will be changed dependent on the printer,
    00038  * according to the value defined at lexmark_cap_t.x_raster_res and
    00039  * lexmark_cap_t.y_raster_res. These two parameters are specifing the
    00040  * resolution used for positioning the printer head (it is not the
    00041  * resolution used for printing!).
    00042  */
    00043
    00044 /* TODO-LIST
    00045  *
    00046  *   * implement the left border
    00047  *
    00048  */
    00049
    00050 /*#define DEBUG 1*/
    00051 #define USEEPSEWAVE 1
    00052
    00053 #ifdef __GNUC__
    00054 #define inline __inline__
    00055 #endif
    00056
    00057 #ifdef HAVE_CONFIG_H
    00058 #include <config.h>
    00059 #endif
    00060 #include <gimp-print/gimp-print.h>
    00061 #include <gimp-print/gimp-print-intl-internal.h>
    00062 #include "gimp-print-internal.h"
    00063 #include <string.h>
    00064 #ifdef DEBUG
    00065 #include <stdio.h>
    00066 #endif
    00067
    00068 #define STP_ECOLOR_LC 4
    00069 #define STP_ECOLOR_LM 5
    00070 #define STP_ECOLOR_LY 6
    00071
    00072 #define false 0
    00073 #define true  1
    00074
    00075 #define max(a, b) ((a > b) ? (a) : (b))
    00076 #define INCH(x)         (72 * x)
    00077
    00078 static const stp_dotsize_t single_dotsize[] =
    00079 {
    00080   { 0x1, 1.0 }
    00081 };
    00082
    00083 static const stp_shade_t photo_dither_shades[] =
    00084 {
    00085   { 1.0000, 1, single_dotsize },
    00086   { 0.3333, 1, single_dotsize },
    00087 };
    00088
    00089
    00090 typedef enum Lex_model { m_lex7500,   m_z52=10052, m_z42=10042, m_3200=3200 } Lex_model;
    00091
    00092 #define NCHANNELS (7)
    00093
    00094 typedef union {                 /* Offsets from the start of each line */
    00095   unsigned long v[NCHANNELS];           /* (really pass) */
    00096   struct {     /* IMPORTANT: order corresponds to STP_ECOLOR_* */
    00097     unsigned long k;
    00098     unsigned long c;
    00099     unsigned long m;
    00100     unsigned long y;
    00101     unsigned long C;
    00102     unsigned long M;
    00103     unsigned long Y;
    00104   } p;
    00105 } lexmark_lineoff_t;
    00106
    00107 typedef union {                 /* Base pointers for each pass */
    00108   unsigned char *v[NCHANNELS];
    00109   struct {     /* IMPORTANT: order corresponds to STP_ECOLOR_* */
    00110     unsigned char *k;
    00111     unsigned char *c;
    00112     unsigned char *m;
    00113     unsigned char *y;
    00114     unsigned char *C;
    00115     unsigned char *M;
    00116     unsigned char *Y;
    00117   } p;
    00118 } lexmark_linebufs_t;
    00119
    00120
    00121
    00122 #ifdef DEBUG
    00123 typedef struct testdata {
    00124   FILE *ifile;
    00125   int x, y, cols, deep;
    00126   char colchar[16];
    00127   char *input_line;
    00128 } testdata;
    00129
    00130 const stp_vars_t **dbgfileprn;
    00131 int  lex_show_lcount, lex_show_length;
    00132
    00133 const stp_vars_t *lex_open_tmp_file();
    00134 const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length);
    00135 static void testprint(testdata *td);
    00136 static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs);
    00137 #endif
    00138
    00139 static void
    00140 flush_pass(stp_vars_t *v, int passno, int vertical_subpass);
    00141
    00142 /*** resolution specific parameters */
    00143 #define DPI300   0
    00144 #define DPI600   1
    00145 #define DPI1200  2
    00146 #define DPI2400  3
    00147 #define DPItest  4
    00148
    00149 #define V_NOZZLE_MASK 0x3
    00150 #define H_NOZZLE_MASK 0xc
    00151 #define NOZZLE_MASK   0xf
    00152
    00153 #define PRINT_MODE_300   0x100
    00154 #define PRINT_MODE_600   0x200
    00155 #define PRINT_MODE_1200  0x300
    00156 #define PRINT_MODE_2400  0x400
    00157
    00158 #define COLOR_MODE_K      0x1000
    00159 #define COLOR_MODE_C      0x2000
    00160 #define COLOR_MODE_Y      0x4000
    00161 #define COLOR_MODE_M      0x8000
    00162 #define COLOR_MODE_LC    0x10000
    00163 #define COLOR_MODE_LY    0x20000
    00164 #define COLOR_MODE_LM    0x40000
    00165 #define COLOR_MODE_CMYK   (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y | COLOR_MODE_K)
    00166 #define COLOR_MODE_CMY    (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y)
    00167 #define COLOR_MODE_CcMcYK (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y | COLOR_MODE_K)
    00168 #define COLOR_MODE_CcMcY  (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y)
    00169
    00170 #define COLOR_MODE_MASK  0x7f000
    00171 #define PRINT_MODE_MASK    0xf00
    00172 #define COLOR_MODE_PHOTO (COLOR_MODE_LC | COLOR_MODE_LM)
    00173
    00174 #define BWR      0
    00175 #define BWL      1
    00176 #define CR       2
    00177 #define CL       3
    00178
    00179
    00180 static const char standard_sat_adjustment[] =
    00181 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    00182 "<gimp-print>\n"
    00183 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
    00184 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
    00185 /* C */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* B */
    00186 /* B */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* M */
    00187 /* M */  "1.00 0.95 0.90 0.90 0.90 0.90 0.90 0.90 "  /* R */
    00188 /* R */  "0.90 0.95 0.95 1.00 1.00 1.00 1.00 1.00 "  /* Y */
    00189 /* Y */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* G */
    00190 /* G */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* C */
    00191 "</sequence>\n"
    00192 "</curve>\n"
    00193 "</gimp-print>\n";
    00194
    00195 static const char standard_lum_adjustment[] =
    00196 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    00197 "<gimp-print>\n"
    00198 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
    00199 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
    00200 /* C */  "0.50 0.52 0.56 0.60 0.66 0.71 0.74 0.77 "  /* B */
    00201 /* B */  "0.81 0.79 0.74 0.68 0.70 0.74 0.77 0.82 "  /* M */
    00202 /* M */  "0.88 0.93 0.95 0.97 0.97 0.96 0.95 0.95 "  /* R */
    00203 /* R */  "0.95 0.96 0.97 0.98 0.99 1.00 1.00 1.00 "  /* Y */
    00204 /* Y */  "1.00 0.97 0.94 0.92 0.90 0.88 0.85 0.79 "  /* G */
    00205 /* G */  "0.69 0.64 0.58 0.54 0.54 0.54 0.53 0.51 "  /* C */
    00206 "</sequence>\n"
    00207 "</curve>\n"
    00208 "</gimp-print>\n";
    00209
    00210 static const char standard_hue_adjustment[] =
    00211 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    00212 "<gimp-print>\n"
    00213 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
    00214 "<sequence count=\"48\" lower-bound=\"-6\" upper-bound=\"6\">\n"
    00215 /* C */  "0.00 0.06 0.10 0.10 0.06 -.01 -.09 -.17 "  /* B */
    00216 /* B */  "-.25 -.33 -.38 -.38 -.36 -.34 -.34 -.34 "  /* M */
    00217 /* M */  "-.34 -.34 -.36 -.40 -.50 -.40 -.30 -.20 "  /* R */
    00218 /* R */  "-.12 -.07 -.04 -.02 0.00 0.00 0.00 0.00 "  /* Y */
    00219 /* Y */  "0.00 0.00 0.00 -.05 -.10 -.15 -.22 -.24 "  /* G */
    00220 /* G */  "-.26 -.30 -.33 -.28 -.25 -.20 -.13 -.06 "  /* C */
    00221 "</sequence>\n"
    00222 "</curve>\n"
    00223 "</gimp-print>\n";
    00224
    00225
    00226 /* Codes for possible ink-tank combinations.
    00227  * Each combo is represented by the colors that can be used with
    00228  * the installed ink-tank(s)
    00229  * Combinations of the codes represent the combinations allowed for a model
    00230  */
    00231 #define LEXMARK_INK_K           1
    00232 #define LEXMARK_INK_CMY         2
    00233 #define LEXMARK_INK_CMYK        4
    00234 #define LEXMARK_INK_CcMmYK      8
    00235 #define LEXMARK_INK_CcMmYy     16
    00236 #define LEXMARK_INK_CcMmYyK    32
    00237
    00238 #define LEXMARK_INK_BLACK_MASK (LEXMARK_INK_K|LEXMARK_INK_CMYK|\
    00239                               LEXMARK_INK_CcMmYK|LEXMARK_INK_CcMmYyK)
    00240
    00241 #define LEXMARK_INK_PHOTO_MASK (LEXMARK_INK_CcMmYy|LEXMARK_INK_CcMmYK|\
    00242                               LEXMARK_INK_CcMmYyK)
    00243
    00244 /* document feeding */
    00245 #define LEXMARK_SLOT_ASF1    1
    00246 #define LEXMARK_SLOT_ASF2    2
    00247 #define LEXMARK_SLOT_MAN1    4
    00248 #define LEXMARK_SLOT_MAN2    8
    00249
    00250 /* model peculiarities */
    00251 #define LEXMARK_CAP_DMT       1<<0    /* Drop Modulation Technology */
    00252 #define LEXMARK_CAP_MSB_FIRST 1<<1    /* how to send data           */
    00253 #define LEXMARK_CAP_CMD61     1<<2    /* uses command #0x61         */
    00254 #define LEXMARK_CAP_CMD6d     1<<3    /* uses command #0x6d         */
    00255 #define LEXMARK_CAP_CMD70     1<<4    /* uses command #0x70         */
    00256 #define LEXMARK_CAP_CMD72     1<<5    /* uses command #0x72         */
    00257
    00258
    00259 static const int lr_shift_color[10] = { 9, 18, 2*18 }; /* vertical distance between ever 2nd  inkjet (related to resolution) */
    00260 static const int lr_shift_black[10] = { 9, 18, 2*18 }; /* vertical distance between ever 2nd  inkjet (related to resolution) */
    00261
    00262 static const stp_parameter_t the_parameters[] =
    00263 {
    00264   {
    00265     "PageSize", N_("Page Size"), N_("Basic Printer Setup"),
    00266     N_("Size of the paper being printed to"),
    00267     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
    00268     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
    00269   },
    00270   {
    00271     "MediaType", N_("Media Type"), N_("Basic Printer Setup"),
    00272     N_("Type of media (plain paper, photo paper, etc.)"),
    00273     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
    00274     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
    00275   },
    00276   {
    00277     "InputSlot", N_("Media Source"), N_("Basic Printer Setup"),
    00278     N_("Source (input slot) of the media"),
    00279     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
    00280     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
    00281   },
    00282   {
    00283     "Resolution", N_("Resolution"), N_("Basic Printer Setup"),
    00284     N_("Resolution and quality of the print"),
    00285     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
    00286     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
    00287   },
    00288   {
    00289     "InkType", N_("Ink Type"), N_("Advanced Printer Setup"),
    00290     N_("Type of ink in the printer"),
    00291     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
    00292     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
    00293   },
    00294   {
    00295     "InkChannels", N_("Ink Channels"), N_("Advanced Printer Functionality"),
    00296     N_("Ink Channels"),
    00297     STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE,
    00298     STP_PARAMETER_LEVEL_INTERNAL, 0, 0, -1, 0, 0
    00299   },
    00300   {
    00301     "PrintingMode", N_("Printing Mode"), N_("Core Parameter"),
    00302     N_("Printing Output Mode"),
    00303     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
    00304     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
    00305   },
    00306 };
    00307
    00308 static const int the_parameter_count =
    00309 sizeof(the_parameters) / sizeof(const stp_parameter_t);
    00310
    00311 typedef struct
    00312 {
    00313   const stp_parameter_t param;
    00314   double min;
    00315   double max;
    00316   double defval;
    00317   int color_only;
    00318 } float_param_t;
    00319
    00320 static const float_param_t float_parameters[] =
    00321 {
    00322   {
    00323     {
    00324       "CyanDensity", N_("Cyan Balance"), N_("Output Level Adjustment"),
    00325       N_("Adjust the cyan balance"),
    00326       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
    00327       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 1, 1, 0
    00328     }, 0.0, 2.0, 1.0, 1
    00329   },
    00330   {
    00331     {
    00332       "MagentaDensity", N_("Magenta Balance"), N_("Output Level Adjustment"),
    00333       N_("Adjust the magenta balance"),
    00334       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
    00335       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 2, 1, 0
    00336     }, 0.0, 2.0, 1.0, 1
    00337   },
    00338   {
    00339     {
    00340       "YellowDensity", N_("Yellow Balance"), N_("Output Level Adjustment"),
    00341       N_("Adjust the yellow balance"),
    00342       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
    00343       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 3, 1, 0
    00344     }, 0.0, 2.0, 1.0, 1
    00345   },
    00346   {
    00347     {
    00348       "BlackDensity", N_("Black Balance"), N_("Output Level Adjustment"),
    00349       N_("Adjust the black balance"),
    00350       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
    00351       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 0, 1, 0
    00352     }, 0.0, 2.0, 1.0, 1
    00353   },
    00354   {
    00355     {
    00356       "LightCyanTransition", N_("Light Cyan Transition"), N_("Advanced Ink Adjustment"),
    00357       N_("Light Cyan Transition"),
    00358       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
    00359       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 1, 0
    00360     }, 0.0, 5.0, 1.0, 1
    00361   },
    00362   {
    00363     {
    00364       "LightMagentaTransition", N_("Light Magenta Transition"), N_("Advanced Ink Adjustment"),
    00365       N_("Light Magenta Transition"),
    00366       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
    00367       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 1, 0
    00368     }, 0.0, 5.0, 1.0, 1
    00369   },
    00370 };
    00371
    00372 static const int float_parameter_count =
    00373 sizeof(float_parameters) / sizeof(const float_param_t);
    00374
    00375 /* returns the offset of the first jet when printing in the other direction */
    00376 static int get_lr_shift(int mode)
    00377 {
    00378
    00379   const int *ptr_lr_shift;
    00380
    00381       /* K could only be present if black is printed only. */
    00382   if((mode & COLOR_MODE_K) == (mode & COLOR_MODE_MASK)) {
    00383     ptr_lr_shift = lr_shift_black;
    00384   } else {
    00385     ptr_lr_shift = lr_shift_color;
    00386   }
    00387
    00388       switch(mode & PRINT_MODE_MASK)    {
    00389         case PRINT_MODE_300:
    00390           return ptr_lr_shift[0];
    00391           break;
    00392         case PRINT_MODE_600:
    00393           return ptr_lr_shift[1];
    00394           break;
    00395         case PRINT_MODE_1200:
    00396           return ptr_lr_shift[2];
    00397           break;
    00398         case PRINT_MODE_2400:
    00399           return ptr_lr_shift[2];
    00400           break;
    00401       }
    00402       return 0;
    00403 }
    00404
    00405
    00406 /*
    00407  * head offsets for z52:
    00408  *
    00409  *      black       black          color         photo
    00410  *    cartridge   cartridge      cartridge     cartridge
    00411  *      mode I     mode II
    00412  *
    00413  *              v                 +-----+ --    +-----+ ---
    00414  * --- +-----+ ---             v  |     | ^     |     |  ^
    00415  *  ^  |     | --- +-----+ --- -- |  C  | 64    | LC  |  |
    00416  *  |  |     |  ^  |     |  ^  40 |     | v  v  |     |  |
    00417  *  |  |     |     |     |  |  -- +-----+ -- -- +-----+  |
    00418  *  |  |     |     |     |  |  ^             28          |
    00419  *  |  |     |     |     |  |     +-----+ -- -- +-----+  |
    00420  *     |     |     |     |  |     |     | ^  ^  |     |  |
    00421  * 208 |  K  |     |  K  | 192    |  M  | 64    | LM  | 240
    00422  *     |     |     |     |  |     |     | v  v  |     |  |
    00423  *  |  |     |     |     |  |     +-----+ -- -- +-----+  |
    00424  *  |  |     |     |     |  |  v             28          |
    00425  *  |  |     |     |     |  |  -- +-----+ -- -- +-----+  |
    00426  *  |  |     |     |     |  v  40 |     | ^  ^  |     |  |
    00427  *  v  |     |     +-----+ --- -- |  Y  | 64    |  K  |  |
    00428  * --- +-----+                 ^  |     | v     |     |  v
    00429  *                                +-----+ --    +-----+ ---
    00430  *
    00431  */
    00432
    00433 static const int head_offset_cmyk[] =
    00434 {70, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
    00435 /* the head_offset_cmy is needed because the dithering code is going into troubles if there is an offset different from 0 for the unused black color */
    00436 static const int head_offset_cmy[] =
    00437 {0, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
    00438 static const int head_offset_cCmMyk[] =
    00439 {0, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
    00440
    00441
    00442
    00443
    00444 /**************************************************************************/
    00445 /**** Data structures which are describing printer specific parameters ****/
    00446
    00447 /* resolution specific parameters (substructure of lexmark_cap_t) */
    00448 typedef struct {
    00449   const char *name;
    00450   const char *text;
    00451   int hres;
    00452   int vres;
    00453   int softweave;
    00454   int vertical_passes;
    00455   int vertical_oversample;
    00456   int unidirectional;      /* print bi/unidirectional */
    00457   int resid;               /* resolution id */
    00458 } lexmark_res_t;
    00459
    00460 #define LEXM_RES_COUNT 30
    00461 typedef lexmark_res_t lexmark_res_t_array[LEXM_RES_COUNT];
    00462
    00463
    00464 /* ink type parameters (substructure of lexmark_cap_t) */
    00465 typedef struct {
    00466   int ncolors;
    00467   unsigned int used_colors; /* specifies the head colors to be used (e.g. COLOR_MODE_K */
    00468   unsigned int pass_length; /* avaliable jets for one color */
    00469   int v_top_head_offset;    /* offset from top, wehere the first jet will be found */
    00470   int h_catridge_offset;    /* horizontal offset of cartridges */
    00471   int h_direction_offset;   /* Offset when printing in the other direction */
    00472   const int *head_offset;   /* specifies the offset of head colors */
    00473 } lexmark_inkparam_t;
    00474
    00475 typedef struct
    00476 {
    00477   const char *name;
    00478   const char *text;
    00479   lexmark_inkparam_t ink_parameter[2];
    00480 } lexmark_inkname_t;
    00481
    00482
    00483 /* main structure which describes all printer specific parameters */
    00484 typedef struct {
    00485   Lex_model model;    /* printer model */
    00486   int max_paper_width;  /* maximum printable paper size in 1/72 inch */
    00487   int max_paper_height;
    00488   int min_paper_width;  /* Maximum paper width, in points */
    00489   int min_paper_height; /* Maximum paper height, in points */
    00490   int max_xdpi;
    00491   int max_ydpi;
    00492   int max_quality;
    00493   int border_left;    /* unit is 72 DPI */
    00494   int border_right;
    00495   int border_top;
    00496   int border_bottom;
    00497   int inks;           /* installable cartridges (LEXMARK_INK_*) */
    00498   int slots;          /* available paperslots */
    00499   int features;       /* special bjl settings */
    00500   /*** printer internal parameters ***/
    00501   /* the unit of the following parameters is identical with max phys unit of the printer */
    00502   int offset_left_border;      /* Offset to the left paper border (== border_left=0) */
    00503   int offset_top_border;       /* Offset to the top paper border (== border_top=0) */
    00504   int x_raster_res;            /* horizontal resolution for positioning of the printer head in DPI */
    00505   int y_raster_res;            /* vertical   resolution for positioning of the printer head in DPI */
    00506   const lexmark_res_t_array *res_parameters; /* resolution specific parameters; last entry has resid = -1 */
    00507   const lexmark_inkname_t *ink_types;  /* type of supported inks */
    00508   const char *lum_adjustment;
    00509   const char *hue_adjustment;
    00510   const char *sat_adjustment;
    00511 } lexmark_cap_t;
    00512
    00513
    00514 /*****************************************************************/
    00515 /**** initialize printer specific data structures ****/
    00516
    00517 /*
    00518  * z52 specific parameters
    00519  */
    00520 #define LX_Z52_300_DPI  1
    00521 #define LX_Z52_600_DPI  3
    00522 #define LX_Z52_1200_DPI 4
    00523 #define LX_Z52_2400_DPI 5
    00524
    00525 #define LX_Z52_COLOR_PRINT 0
    00526 #define LX_Z52_BLACK_PRINT 1
    00527
    00528 #define LX_PSHIFT                   0x13
    00529 #define LX_Z52_COLOR_MODE_POS       0x9
    00530 #define LX_Z52_RESOLUTION_POS       0x7
    00531 #define LX_Z52_PRINT_DIRECTION_POS  0x8
    00532
    00533 /*static const int IDX_Z52ID =2;*/
    00534 static const int IDX_SEQLEN=3;
    00535
    00536 /*
    00537    head:
    00538      1 .. black,
    00539      0 .. color
    00540
    00541    resolution:
    00542      1 .. 300 dpi (for black ?)
    00543      2 .. like 1
    00544      3 .. 600 dpi (color&black)
    00545      4 .. 1200 dpi
    00546      5 .. ? like 1
    00547 */
    00548
    00549 #define LXM_Z52_HEADERSIZE 34
    00550 static const unsigned char outbufHeader_z52[LXM_Z52_HEADERSIZE]=
    00551 {
    00552   0x1B,0x2A,0x24,0x00,0x00,0xFF,0xFF,         /* number of packets ----     vvvvvvvvv */
    00553   0x01,0x01,0x01,0x1a,0x03,0x01,              /* 0x7-0xc: resolution, direction, head */
    00554   0x03,0x60,                                  /* 0xd-0xe HE */
    00555   0x04,0xe0,                                  /* 0xf-0x10  HS vertical pos */
    00556   0x19,0x5c,                                  /* 0x11-0x12 */
    00557   0x0,0x0,                                    /* 0x13-0x14  VO between packges*/
    00558   0x0,0x80,                                   /* 0x15-0x16 */
    00559   0x0,0x0,0x0,0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x0 /* 0x17-0x21 */
    00560 };
    00561
    00562 #define LXM_Z42_HEADERSIZE 34
    00563 static const unsigned char outbufHeader_z42[LXM_Z42_HEADERSIZE]=
    00564 {
    00565   0x1B,0x2A,0x24,0x00,0x00,0x00,0x00,
    00566   0x01,0x01,0x01,0x18,0x00,0x01,0x00,
    00567   0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    00568   0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    00569   0x00,0x00,0x00,0x00,0x00,0x00
    00570 };
    00571
    00572
    00573 static const lexmark_res_t_array lexmark_reslist_z52 =  /* LEXM_RES_COUNT entries are allowed !! */
    00574 {
    00575   /*     name                                                    hres vres softw v_pass overs unidir resid */
    00576   { "300x600dpi",     N_ ("300 DPI x 600 DPI"),                  300,  600,  0,    1,    1,    0,    DPI300 },
    00577   { "600dpi",         N_ ("600 DPI"),                            600,  600,  0,    1,    1,    0,    DPI600 },
    00578   { "600hq",          N_ ("600 DPI high quality"),               600,  600,  1,    4,    1,    0,    DPI600 },
    00579   { "600uni",         N_ ("600 DPI Unidirectional"),             600,  600,  0,    1,    1,    1,    DPI600 },
    00580   { "1200dpi",        N_ ("1200 DPI"),                          1200, 1200,  1,    1,    1,    0,    DPI1200},
    00581   { "1200hq",         N_ ("1200 DPI high quality"),             1200, 1200,  1,    1,    1,    0,    DPI300 },
    00582   { "1200hq2",        N_ ("1200 DPI highest quality"),          1200, 1200,  1,    1,    1,    0,    DPI600 },
    00583   { "1200uni",        N_ ("1200 DPI  Unidirectional"),          1200, 1200,  0,    1,    1,    1,    DPI1200},
    00584   { "2400x1200dpi",   N_ ("2400 DPI x 1200 DPI"),               2400, 1200,  1,    1,    1,    0,    DPI1200},
    00585   { "2400x1200hq",    N_ ("2400 DPI x 1200 DPI high quality"),  2400, 1200,  1,    1,    1,    0,    DPI600 },
    00586   { "2400x1200hq2",   N_ ("2400 DPI x 1200 DPI highest quality"),2400, 1200,  1,    1,    1,    0,    DPI300},
    00587 #ifdef DEBUG
    00588   { "testprint",      N_ ("test print"),                        1200, 1200,  1,    1,    1,    0,    DPItest},
    00589 #endif
    00590   { "",                 "", 0, 0, 0, 0, 0, -1 }
    00591 };
    00592
    00593
    00594 static const lexmark_inkname_t ink_types_z52[] =
    00595 {
    00596   /*   output_type   ncolors used_colors   pass_length  v_top_head_offset
    00597    *                                                        h_catridge_offset
    00598    *                                                           h_direction_offset
    00599    *                                                               head_offset */
    00600   { "CMYK",     N_("Four Color Standard"),
    00601     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },
    00602      { 4, COLOR_MODE_CMYK,   192/3,   0, 0, 10, head_offset_cmyk }}},
    00603   { "RGB",      N_("Three Color Composite"),
    00604     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },  /* we ignor CMY, use black */
    00605      { 4, COLOR_MODE_CMY,    192/3,   0, 0, 10, head_offset_cmy }}},
    00606   { "PhotoCMYK", N_("Six Color Photo"),
    00607     {{ 1, COLOR_MODE_K,      192/3,   0, 0, 10, head_offset_cCmMyk },
    00608      { 6, COLOR_MODE_CcMcYK, 192/3,   0, 0, 10, head_offset_cCmMyk }}},
    00609   { "PhotoCMY", N_("Five Color Photo Composite"),
    00610     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cCmMyk },
    00611      { 5, COLOR_MODE_CcMcY,  192/3,   0, 0, 10, head_offset_cCmMyk }}}, /* we ignor CMY, use black */
    00612   { "Gray",     N_("Black"),
    00613     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },
    00614      { 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk }}},
    00615   { NULL, NULL }
    00616 };
    00617
    00618
    00619
    00620 /*
    00621  * 3200 sepecific stuff
    00622  */
    00623 #define LXM3200_LEFTOFFS 6254
    00624 #define LXM3200_RIGHTOFFS (LXM3200_LEFTOFFS-2120)
    00625
    00626 static int lxm3200_headpos = 0;
    00627 static int lxm3200_linetoeject = 0;
    00628
    00629 #define LXM_3200_HEADERSIZE 24
    00630 static const char outbufHeader_3200[LXM_3200_HEADERSIZE] =
    00631 {
    00632   0x1b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    00633   0x1b, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    00634   0x1b, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    00635 };
    00636
    00637 static inline int
    00638 lexmark_calc_3200_checksum(unsigned char *data)
    00639 {
    00640   int ck, i;
    00641
    00642   ck = 0;
    00643   for(i=1; i<7; i++)ck += data[i];
    00644
    00645   return(ck & 255);
    00646 }
    00647
    00648
    00649 static const lexmark_res_t_array lexmark_reslist_3200 =   /* LEXM_RES_COUNT entries are allowed !! */
    00650 {
    00651   /*     name                                                    hres vres softw v_pass overs unidir resid */
    00652   { "300x600dpi",     N_ ("300 DPI x 600 DPI"),                  300,  600,  0,    1,    1,    0,    DPI300 },
    00653   { "600dpi",         N_ ("600 DPI"),                            600,  600,  0,    1,    1,    0,    DPI600 },
    00654   { "600hq",          N_ ("600 DPI high quality"),               600,  600,  1,    4,    1,    0,    DPI600 },
    00655   { "600uni",         N_ ("600 DPI Unidirectional"),             600,  600,  0,    1,    1,    1,    DPI600 },
    00656   { "1200dpi",        N_ ("1200 DPI"),                          1200, 1200,  1,    1,    1,    0,    DPI1200},
    00657   { "1200hq",         N_ ("1200 DPI high quality"),             1200, 1200,  1,    1,    1,    0,    DPI300 },
    00658   { "1200hq2",        N_ ("1200 DPI highest quality"),          1200, 1200,  1,    1,    1,    0,    DPI600 },
    00659   { "1200uni",        N_ ("1200 DPI  Unidirectional"),          1200, 1200,  0,    1,    1,    1,    DPI1200},
    00660   { "",                 "", 0, 0, 0, 0, 0, -1 }
    00661 };
    00662
    00663
    00664 static const lexmark_inkname_t ink_types_3200[] =
    00665 {
    00666   /*   output_type   ncolors used_colors   pass_length  v_top_head_offset
    00667    *                                                        h_catridge_offset
    00668    *                                                           h_direction_offset
    00669    *                                                               head_offset */
    00670   { "CMYK",     N_("Four Color Standard"),
    00671     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cmyk },
    00672      { 4, COLOR_MODE_CMYK,   192/3,   0, 0, 12, head_offset_cmyk }}},
    00673   { "RGB",      N_("Three Color Composite"),
    00674     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cmyk },  /* we ignor CMY, use black */
    00675      { 4, COLOR_MODE_CMY,    192/3,   0, 0, 12, head_offset_cmy }}},
    00676   { "PhotoCMYK", N_("Six Color Photo"),
    00677     {{ 1, COLOR_MODE_K,      192/3,   0, 0, 12, head_offset_cCmMyk },
    00678      { 6, COLOR_MODE_CcMcYK, 192/3,   0, 0, 12, head_offset_cCmMyk }}},
    00679   { "PhotoCMY", N_("Five Color Photo Composite"),
    00680     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cCmMyk }, /* we ignor CMY, use black */
    00681      { 5, COLOR_MODE_CcMcY,  192/3,   0, 0, 12, head_offset_cCmMyk }}},
    00682   { NULL, NULL }
    00683 };
    00684
    00685
    00686
    00687
    00688
    00689 /* main structure */
    00690 static const lexmark_cap_t lexmark_model_capabilities[] =
    00691 {
    00692   /* default settings for unkown models */
    00693
    00694   {   (Lex_model)-1, 8*72,11*72,180,180,20,20,20,20, LEXMARK_INK_K, LEXMARK_SLOT_ASF1, 0 },
    00695
    00696   /* tested models */
    00697
    00698   { /* Lexmark z52 */
    00699     m_z52,
    00700     618, 936,         /* max paper size *//* 8.58" x 13 " */
    00701     INCH(2), INCH(4), /* min paper size */
    00702     2400, 1200, 2, /* max resolution */
    00703     0, 0, 5, 15, /* 15 36 border l,r,t,b    unit is 1/72 DPI */
    00704     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
    00705     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
    00706     LEXMARK_CAP_DMT,
    00707     /*** printer internal parameters ***/
    00708     20,        /* real left paper border */
    00709     123,       /* real top paper border */
    00710     2400,      /* horizontal resolution of 2400 dpi for positioning */
    00711     1200,      /* use a vertical resolution of 1200 dpi for positioning */
    00712     &lexmark_reslist_z52,  /* resolution specific parameters of z52 */
    00713     ink_types_z52,  /* supported inks */
    00714     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
    00715   },
    00716   { /* Lexmark z42 */
    00717     m_z42,
    00718     618, 936,         /* max paper size *//* 8.58" x 13 " */
    00719     INCH(2), INCH(4), /* min paper size */
    00720     2400, 1200, 2, /* max resolution */
    00721     0, 0, 5, 41, /* border l,r,t,b    unit is 1/72 DPI */
    00722     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
    00723     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
    00724     LEXMARK_CAP_DMT,
    00725     /*** printer internal parameters ***/
    00726     20,        /* real left paper border */
    00727     123,       /* real top paper border */
    00728     2400,      /* horizontal resolution of 2400 dpi for positioning */
    00729     1200,      /* use a vertical resolution of 1200 dpi for positioning */
    00730     &lexmark_reslist_z52,  /* resolution specific parameters of z52 */
    00731     ink_types_z52,  /* supported inks */
    00732     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
    00733   },
    00734   { /* Lexmark 3200 */
    00735     m_3200,
    00736     618, 936,      /* 8.58" x 13 " */
    00737     INCH(2), INCH(4), /* min paper size */
    00738     1200, 1200, 2,
    00739     11, 9, 10, 18,
    00740     LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
    00741     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
    00742     LEXMARK_CAP_DMT,
    00743     /*** printer internal parameters ***/
    00744     0,         /* real left paper border */
    00745     300,       /* real top paper border */
    00746     1200,      /* horizontal resolution of ?? dpi for positioning */
    00747     1200,      /* use a vertical resolution of 1200 dpi for positioning */
    00748     &lexmark_reslist_3200,  /* resolution specific parameters of 3200 */
    00749     ink_types_3200,  /* supported inks */
    00750     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
    00751   },
    00752   { /*  */
    00753     m_lex7500,
    00754     618, 936,      /* 8.58" x 13 " */
    00755     INCH(2), INCH(4), /* min paper size */
    00756     2400, 1200, 2,
    00757     11, 9, 10, 18,
    00758     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
    00759     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
    00760     LEXMARK_CAP_DMT,
    00761     /*** printer internal parameters ***/
    00762     0,         /* real left paper border */
    00763     300,       /* real top paper border */
    00764     1200,      /* horizontal resolutio of ??? dpi for positioning */
    00765     1200,      /* use a vertical resolution of 1200 dpi for positioning */
    00766     &lexmark_reslist_3200,  /* resolution specific parameters of ?? */
    00767     ink_types_3200,  /* supported inks */
    00768     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
    00769   },
    00770 };
    00771
    00772
    00773
    00774
    00775
    00776 typedef struct lexm_privdata_weave {
    00777   const lexmark_inkparam_t *ink_parameter;
    00778   int           bidirectional; /* tells us if we are allowed to print bidirectional */
    00779   int           direction;     /* stores the last direction or print head */
    00780   int           hoffset;
    00781   int model;
    00782   int width;
    00783   int ydpi;
    00784   int xdpi;
    00785   int physical_xdpi;
    00786   int last_pass_offset;
    00787   int jets;
    00788   int bitwidth;
    00789   int ncolors;
    00790   int horizontal_weave;
    00791   unsigned char *outbuf;
    00792 } lexm_privdata_weave;
    00793
    00794
    00795 /*
    00796  * internal functions
    00797  */
    00798 static int model_to_index(int model)
    00799 {
    00800   int i;
    00801   int models= sizeof(lexmark_model_capabilities) / sizeof(lexmark_cap_t);
    00802   for (i=0; i<models; i++) {
    00803     if (lexmark_model_capabilities[i].model == model) {
    00804       return i;
    00805     }
    00806   }
    00807   return -1;
    00808 }
    00809
    00810
    00811 static const lexmark_cap_t *
    00812 lexmark_get_model_capabilities(int model)
    00813 {
    00814   int i = model_to_index(model);
    00815
    00816   if (i != -1) {
    00817     return &(lexmark_model_capabilities[i]);
    00818   }
    00819 #ifdef DEBUG
    00820   stp_erprintf("lexmark: model %d not found in capabilities list.\n",model);
    00821 #endif
    00822   return &(lexmark_model_capabilities[0]);
    00823 }
    00824
    00825
    00826
    00827 typedef struct
    00828 {
    00829   const char *name;
    00830   const char *text;
    00831   int paper_feed_sequence;
    00832   int platen_gap;
    00833   double base_density;
    00834   double k_lower_scale;
    00835   double k_upper;
    00836   double cyan;
    00837   double magenta;
    00838   double yellow;
    00839   double p_cyan;
    00840   double p_magenta;
    00841   double p_yellow;
    00842   double saturation;
    00843   double gamma;
    00844   int feed_adjustment;
    00845   int vacuum_intensity;
    00846   int paper_thickness;
    00847   const char *hue_adjustment;
    00848   const char *lum_adjustment;
    00849   const char *sat_adjustment;
    00850 } paper_t;
    00851
    00852
    00853
    00854 static const paper_t lexmark_paper_list[] =
    00855 {
    00856   { "Plain", N_("Plain Paper"),
    00857     1, 0, 0.80, .1, .5, 1.0, 1.0, 1.0, .9, 1.05, 1.15,
    00858     1, 1.0, 0x6b, 0x1a, 0x01,
    00859     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00860   { "GlossyFilm", N_("Glossy Film"),
    00861     3, 0, 1.00 ,1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00862     1, 1.0, 0x6d, 0x00, 0x01,
    00863     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00864   { "Transparency", N_("Transparencies"),
    00865     3, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00866     1.0, 1.0, 0x6d, 0x00, 0x02,
    00867     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00868   { "Envelope", N_("Envelopes"),
    00869     4, 0, 0.80, .125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00870     1, 1.0, 0x6b, 0x1a, 0x01,
    00871     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00872   { "Matte", N_("Matte Paper"),
    00873     7, 0, 0.85, 1.0, .999, 1.05, .9, 1.05, .9, 1.0, 1.1,
    00874     1, 1.0, 0x00, 0x00, 0x02,
    00875     standard_hue_adjustment, standard_sat_adjustment, standard_sat_adjustment},
    00876   { "Inkjet", N_("Inkjet Paper"),
    00877     7, 0, 0.85, .25, .6, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00878     1, 1.0, 0x6b, 0x1a, 0x01,
    00879     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00880   { "Coated", N_("Photo Quality Inkjet Paper"),
    00881     7, 0, 1.00, 1.0, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00882     1, 1.0, 0x6b, 0x1a, 0x01,
    00883     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00884   { "Photo", N_("Photo Paper"),
    00885     8, 0, 1.00, 1.0, .9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00886     1, 1.0, 0x67, 0x00, 0x02,
    00887     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00888   { "GlossyPhoto", N_("Premium Glossy Photo Paper"),
    00889     8, 0, 1.10, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.03, 1.0,
    00890     1, 1.0, 0x80, 0x00, 0x02,
    00891     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00892   { "Luster", N_("Premium Luster Photo Paper"),
    00893     8, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00894     1.0, 1.0, 0x80, 0x00, 0x02,
    00895     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00896   { "GlossyPaper", N_("Photo Quality Glossy Paper"),
    00897     6, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00898     1.0, 1.0, 0x6b, 0x1a, 0x01,
    00899     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00900   { "Ilford", N_("Ilford Heavy Paper"),
    00901     8, 0, .85, .5, 1.35, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00902     1, 1.0, 0x80, 0x00, 0x02,
    00903     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00904   { "Other", N_("Other"),
    00905     0, 0, 0.80, 0.125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
    00906     1, 1.0, 0x6b, 0x1a, 0x01,
    00907     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
    00908 };
    00909
    00910 static const int paper_type_count = sizeof(lexmark_paper_list) / sizeof(paper_t);
    00911
    00912 static const lexmark_inkname_t *
    00913 lexmark_get_ink_type(const char *name, int printing_color, const lexmark_cap_t * caps)
    00914 {
    00915   int i = 0;
    00916   const lexmark_inkname_t *ink_type = caps->ink_types;
    00917
    00918   if (name)
    00919     for (i=0; ((ink_type[i].name != NULL) &&
    00920                (strcmp(name, ink_type[i].name)  != 0)); i++) ;
    00921   return &(ink_type[i]);
    00922
    00923 }
    00924
    00925 static const lexmark_inkparam_t *
    00926 lexmark_get_ink_parameter(const char *name, int printing_color, const lexmark_cap_t * caps, const stp_vars_t *nv)
    00927 {
    00928   const lexmark_inkname_t *ink_type = lexmark_get_ink_type(name, printing_color, caps);
    00929
    00930   if (ink_type->name == NULL) {
    00931     return (NULL); /* not found ! */
    00932   }
    00933
    00934   return &(ink_type->ink_parameter[printing_color]);
    00935 }
    00936
    00937
    00938 static const paper_t *
    00939 get_media_type(const char *name, const lexmark_cap_t * caps)
    00940 {
    00941   int i;
    00942   if (name)
    00943     {
    00944       for (i = 0; i < paper_type_count; i++)
    00945         {
    00946           if (!strcmp(name, lexmark_paper_list[i].name))
    00947             return &(lexmark_paper_list[i]);
    00948         }
    00949     }
    00950   return NULL;
    00951 }
    00952
    00953 static int
    00954 lexmark_source_type(const char *name, const lexmark_cap_t * caps)
    00955 {
    00956   if (name)
    00957     {
    00958       if (!strcmp(name,"Auto"))    return 4;
    00959       if (!strcmp(name,"Manual"))    return 0;
    00960       if (!strcmp(name,"ManualNP")) return 1;
    00961     }
    00962
    00963 #ifdef DEBUG
    00964   stp_erprintf("lexmark: Unknown source type '%s' - reverting to auto\n",name);
    00965 #endif
    00966   return 4;
    00967 }
    00968
    00969
    00970
    00971 /*******************************
    00972 lexmark_head_offset
    00973 *******************************/
    00974 static const lexmark_lineoff_t *
    00975 lexmark_head_offset(int ydpi,                       /* i */
    00976                     const char *ink_type,           /* i */
    00977                     const lexmark_cap_t * caps,     /* i */
    00978                     const lexmark_inkparam_t *ink_parameter, /* i */
    00979                     lexmark_lineoff_t *lineoff_buffer)  /* o */
    00980 {
    00981   int i;
    00982
    00983 #ifdef DEBUG
    00984   stp_erprintf("  sizie %d,  size_v %d, size_v[0] %d\n", sizeof(*lineoff_buffer), sizeof(lineoff_buffer->v), sizeof(lineoff_buffer->v[0]));
    00985 #endif
    00986   memcpy(lineoff_buffer, ink_parameter->head_offset, sizeof(*lineoff_buffer));
    00987
    00988   for (i=0; i < (sizeof(lineoff_buffer->v) / sizeof(lineoff_buffer->v[0])); i++) {
    00989     lineoff_buffer->v[i] /= (caps->y_raster_res / ydpi);
    00990   }
    00991   return (lineoff_buffer);
    00992 }
    00993
    00994
    00995 #if 0
    00996 /*******************************
    00997 lexmark_size_type
    00998 *******************************/
    00999 /* This method is actually not used.
    01000    Is there a possibility to set such value ???????????? */
    01001 static unsigned char
    01002 lexmark_size_type(const stp_vars_t *v, const lexmark_cap_t * caps)
    01003 {
    01004   const stp_papersize_t *pp = stp_get_papersize_by_size(stp_get_page_height(v),
    01005                                                         stp_get_page_width(v));
    01006   if (pp)
    01007     {
    01008       const char *name = pp->name;
    01009       /* built ins: */
    01010       if (!strcmp(name,"A5"))           return 0x01;
    01011       if (!strcmp(name,"A4"))           return 0x03;
    01012       if (!strcmp(name,"B5"))           return 0x08;
    01013       if (!strcmp(name,"Letter"))       return 0x0d;
    01014       if (!strcmp(name,"Legal"))        return 0x0f;
    01015       if (!strcmp(name,"COM10"))        return 0x16;
    01016       if (!strcmp(name,"DL"))           return 0x17;
    01017       if (!strcmp(name,"LetterExtra"))  return 0x2a;
    01018       if (!strcmp(name,"A4Extra"))      return 0x2b;
    01019       if (!strcmp(name,"w288h144"))     return 0x2d;
    01020       /* custom */
    01021
    01022 #ifdef DEBUG
    01023       stp_erprintf("lexmark: Unknown paper size '%s' - using custom\n",name);
    01024     } else {
    01025       stp_erprintf("lexmark: Couldn't look up paper size %dx%d - "
    01026               "using custom\n",stp_get_page_height(v), stp_get_page_width(v));
    01027 #endif
    01028     }
    01029   return 0;
    01030 }
    01031 #endif
    01032
    01033
    01034 static int lexmark_get_phys_resolution_vertical(int model)
    01035 {
    01036   return 600;
    01037 }
    01038
    01039 #if 0
    01040 static int lexmark_get_phys_resolution_horizontal(int model)
    01041 {
    01042   return 1200;
    01043 }
    01044 #endif
    01045
    01046 static const lexmark_res_t
    01047 *lexmark_get_resolution_para(int model, const char *resolution)
    01048 {
    01049   const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
    01050
    01051   const lexmark_res_t *res = *(caps->res_parameters); /* get the resolution specific parameters of printer */
    01052
    01053   if (resolution)
    01054     {
    01055       while (res->hres)
    01056         {
    01057           if ((res->vres <= caps->max_ydpi) && (caps->max_ydpi != -1) &&
    01058               (res->hres <= caps->max_xdpi) && (caps->max_xdpi != -1) &&
    01059               (!strcmp(resolution, res->name)))
    01060             {
    01061               return res;
    01062             }
    01063           res++;
    01064         }
    01065     }
    01066   stp_erprintf("lexmark_get_resolution_para: resolution not found (%s)\n", resolution);
    01067   return NULL;
    01068 }
    01069
    01070
    01071 static int
    01072 lexmark_print_bidirectional(int model, const char *resolution)
    01073 {
    01074   const lexmark_res_t *res_para = lexmark_get_resolution_para(model, resolution);
    01075   return !res_para->unidirectional;
    01076 }
    01077
    01078 static const char *
    01079 lexmark_lum_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
    01080 {
    01081   return (caps->lum_adjustment);
    01082 }
    01083
    01084 static const char *
    01085 lexmark_hue_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
    01086 {
    01087   return (caps->hue_adjustment);
    01088 }
    01089
    01090 static const char *
    01091 lexmark_sat_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
    01092 {
    01093   return (caps->sat_adjustment);
    01094 }
    01095
    01096
    01097 static void
    01098 lexmark_describe_resolution(const stp_vars_t *v, int *x, int *y)
    01099 {
    01100   const char *resolution = stp_get_string_parameter(v, "Resolution");
    01101   const lexmark_res_t *res =
    01102     lexmark_get_resolution_para(stp_get_model_id(v), resolution);
    01103
    01104   if (res)
    01105     {
    01106       *x = res->hres;
    01107       *y = res->vres;
    01108       return;
    01109     }
    01110   *x = -1;
    01111   *y = -1;
    01112 }
    01113
    01114
    01115 static stp_param_string_t media_sources[] =
    01116 {
    01117   { "Auto",             N_("Auto Sheet Feeder") },
    01118   { "Manual",           N_("Manual with Pause") },
    01119   { "ManualNP",         N_("Manual without Pause") }
    01120 };
    01121
    01122
    01123 /*
    01124  * 'lexmark_parameters()' - Return the parameter values for the given parameter.
    01125  */
    01126
    01127 static stp_parameter_list_t
    01128 lexmark_list_parameters(const stp_vars_t *v)
    01129 {
    01130   stp_parameter_list_t *ret = stp_parameter_list_create();
    01131   int i;
    01132   for (i = 0; i < the_parameter_count; i++)
    01133     stp_parameter_list_add_param(ret, &(the_parameters[i]));
    01134   for (i = 0; i < float_parameter_count; i++)
    01135     stp_parameter_list_add_param(ret, &(float_parameters[i].param));
    01136   return ret;
    01137 }
    01138
    01139 static const char *
    01140 lexmark_describe_output(const stp_vars_t *v)
    01141 {
    01142   int printing_color = 0;
    01143   int model = stp_get_model_id(v);
    01144   const lexmark_cap_t *caps = lexmark_get_model_capabilities(model);
    01145   const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
    01146   const char *ink_type = stp_get_string_parameter(v, "InkType");
    01147   const lexmark_inkparam_t *ink_parameter;
    01148
    01149   if (!print_mode || strcmp(print_mode, "Color") == 0)
    01150     printing_color = 1;
    01151
    01152   ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
    01153
    01154   if (ink_parameter->used_colors == COLOR_MODE_K ||
    01155       caps->inks == LEXMARK_INK_K || !printing_color)
    01156     return "Grayscale";
    01157   else if (!(ink_parameter->used_colors & COLOR_MODE_K))
    01158     return "CMY";
    01159   else
    01160     return "CMYK";
    01161 }
    01162
    01163 static void
    01164 lexmark_parameters(const stp_vars_t *v, const char *name,
    01165                    stp_parameter_t *description)
    01166 {
    01167   int           i;
    01168
    01169   const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_get_model_id(v));
    01170   description->p_type = STP_PARAMETER_TYPE_INVALID;
    01171
    01172   if (name == NULL)
    01173     return;
    01174
    01175   for (i = 0; i < float_parameter_count; i++)
    01176     if (strcmp(name, float_parameters[i].param.name) == 0)
    01177       {
    01178         stp_fill_parameter_settings(description,
    01179                                     &(float_parameters[i].param));
    01180         description->deflt.dbl = float_parameters[i].defval;
    01181         description->bounds.dbl.upper = float_parameters[i].max;
    01182         description->bounds.dbl.lower = float_parameters[i].min;
    01183         return;
    01184       }
    01185
    01186   for (i = 0; i < the_parameter_count; i++)
    01187     if (strcmp(name, the_parameters[i].name) == 0)
    01188       {
    01189         stp_fill_parameter_settings(description, &(the_parameters[i]));
    01190         break;
    01191       }
    01192
    01193   if (strcmp(name, "PageSize") == 0)
    01194   {
    01195     unsigned int height_limit, width_limit;
    01196     unsigned int min_height_limit, min_width_limit;
    01197     int papersizes = stp_known_papersizes();
    01198     description->bounds.str = stp_string_list_create();
    01199
    01200     width_limit  = caps->max_paper_width;
    01201     height_limit = caps->max_paper_height;
    01202     min_width_limit  = caps->min_paper_width;
    01203     min_height_limit = caps->min_paper_height;
    01204
    01205     for (i = 0; i < papersizes; i++) {
    01206       const stp_papersize_t *pt = stp_get_papersize_by_index(i);
    01207       if (strlen(pt->name) > 0 &&
    01208           pt->width <= width_limit && pt->height <= height_limit &&
    01209           (pt->height >= min_height_limit || pt->height == 0) &&
    01210           (pt->width >= min_width_limit || pt->width == 0))
    01211         {
    01212           if (stp_string_list_count(description->bounds.str) == 0)
    01213             description->deflt.str = pt->name;
    01214           stp_string_list_add_string(description->bounds.str,
    01215                                      pt->name, pt->text);
    01216         }
    01217     }
    01218   }
    01219   else if (strcmp(name, "Resolution") == 0)
    01220   {
    01221     const lexmark_res_t *res;
    01222     description->bounds.str = stp_string_list_create();
    01223
    01224     res =  *(caps->res_parameters); /* get resolution specific parameters of printer */
    01225
    01226     /* check for allowed resolutions */
    01227     while (res->hres)
    01228       {
    01229         if (stp_string_list_count(description->bounds.str) == 0)
    01230           description->deflt.str = res->name;
    01231         stp_string_list_add_string(description->bounds.str,
    01232                                   res->name, _(res->text));
    01233         res++;
    01234       }
    01235   }
    01236   else if (strcmp(name, "InkType") == 0)
    01237   {
    01238     description->bounds.str = stp_string_list_create();
    01239     description->deflt.str = caps->ink_types[0].name;
    01240     for (i = 0; caps->ink_types[i].name != NULL; i++)
    01241       stp_string_list_add_string(description->bounds.str,
    01242                                caps->ink_types[i].name,
    01243                                _(caps->ink_types[i].text));
    01244   }
    01245   else if (strcmp(name, "MediaType") == 0)
    01246   {
    01247     description->bounds.str = stp_string_list_create();
    01248     description->deflt.str = lexmark_paper_list[0].name;
    01249     for (i = 0; i < paper_type_count; i++)
    01250       stp_string_list_add_string(description->bounds.str,
    01251                                lexmark_paper_list[i].name,
    01252                                _(lexmark_paper_list[i].text));
    01253   }
    01254   else if (strcmp(name, "InputSlot") == 0)
    01255   {
    01256     description->bounds.str = stp_string_list_create();
    01257     description->deflt.str = media_sources[0].name;
    01258     for (i = 0; i < sizeof(media_sources) / sizeof(stp_param_string_t); i++)
    01259       stp_string_list_add_string(description->bounds.str,
    01260                                media_sources[i].name,
    01261                                _(media_sources[i].name));
    01262   }
    01263   else if (strcmp(name, "InkChannels") == 0)
    01264     {
    01265       if (caps->inks & LEXMARK_INK_CcMmYyK)
    01266         description->deflt.integer = 7;
    01267       else if (caps->inks & LEXMARK_INK_CcMmYK)
    01268         description->deflt.integer = 6;
    01269       else if (caps->inks & LEXMARK_INK_CMYK)
    01270         description->deflt.integer = 4;
    01271       else if (caps->inks & LEXMARK_INK_CMY)
    01272         description->deflt.integer = 3;
    01273       else
    01274         description->deflt.integer = 1;
    01275       description->bounds.integer.lower = -1;
    01276       description->bounds.integer.upper = -1;
    01277     }
    01278   else if (strcmp(name, "PrintingMode") == 0)
    01279     {
    01280       description->bounds.str = stp_string_list_create();
    01281       stp_string_list_add_string
    01282         (description->bounds.str, "Color", _("Color"));
    01283       stp_string_list_add_string
    01284         (description->bounds.str, "BW", _("Black and White"));
    01285       description->deflt.str =
    01286         stp_string_list_param(description->bounds.str, 0)->name;
    01287     }
    01288 }
    01289
    01290 /*
    01291  * 'lexmark_imageable_area()' - Return the imageable area of the page.
    01292  */
    01293
    01294 static void
    01295 internal_imageable_area(const stp_vars_t *v,   /* I */
    01296                         int  use_paper_margins,
    01297                         int  *left,     /* O - Left position in points */
    01298                         int  *right,    /* O - Right position in points */
    01299                         int  *bottom,   /* O - Bottom position in points */
    01300                         int  *top)      /* O - Top position in points */
    01301 {
    01302   int   width, length;                  /* Size of page */
    01303   int left_margin = 0;
    01304   int right_margin = 0;
    01305   int bottom_margin = 0;
    01306   int top_margin = 0;
    01307   const char *media_size = stp_get_string_parameter(v, "PageSize");
    01308   const stp_papersize_t *pt = NULL;
    01309   const lexmark_cap_t *caps =
    01310     lexmark_get_model_capabilities(stp_get_model_id(v));
    01311
    01312
    01313   if (media_size && use_paper_margins)
    01314     pt = stp_get_papersize_by_name(media_size);
    01315
    01316   stp_default_media_size(v, &width, &length);
    01317   if (pt)
    01318     {
    01319       left_margin = pt->left;
    01320       right_margin = pt->right;
    01321       bottom_margin = pt->bottom;
    01322       top_margin = pt->top;
    01323     }
    01324   left_margin = max(left_margin, caps->border_left);
    01325   right_margin = max(right_margin, caps->border_right);
    01326   top_margin = max(top_margin, caps->border_top);
    01327   bottom_margin = max(bottom_margin, caps->border_bottom);
    01328
    01329   *left =       left_margin;
    01330   *right =      width - right_margin;
    01331   *top =        top_margin;
    01332   *bottom =     length - bottom_margin;
    01333 }
    01334
    01335 static void
    01336 lexmark_imageable_area(const stp_vars_t *v,   /* I */
    01337                        int  *left,      /* O - Left position in points */
    01338                        int  *right,     /* O - Right position in points */
    01339                        int  *bottom,    /* O - Bottom position in points */
    01340                        int  *top)       /* O - Top position in points */
    01341 {
    01342   internal_imageable_area(v, 1, left, right, bottom, top);
    01343 }
    01344
    01345 static void
    01346 lexmark_limit(const stp_vars_t *v,              /* I */
    01347               int *width,
    01348               int *height,
    01349               int *min_width,
    01350               int *min_height)
    01351 {
    01352   const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_get_model_id(v));
    01353   *width =      caps->max_paper_width;
    01354   *height =     caps->max_paper_height;
    01355   *min_width =  caps->min_paper_width;
    01356   *min_height = caps->min_paper_height;
    01357 }
    01358
    01359
    01360
    01361 static int
    01362 lexmark_init_printer(const stp_vars_t *v, const lexmark_cap_t * caps,
    01363                      int printing_color,
    01364                      const char *source_str,
    01365                      int xdpi, int ydpi,
    01366                      int page_width, int page_height,
    01367                      int top, int left,
    01368                      int use_dmt)
    01369 {
    01370
    01371   /* because the details of the header sequence are not known, we simply write it as one image. */
    01372
    01373 #define LXM_Z52_STARTSIZE 0x35
    01374   /* 300 dpi */
    01375   unsigned char startHeader_z52[LXM_Z52_STARTSIZE]={0x1b,0x2a,0x81,0x00,0x1c,0x56,0x49,0x00,
    01376                                            0x01,0x00,0x2c,0x01,0x00,0x00,0x60,0x09,
    01377                                            0xe4,0x0c,0x01,0x00,0x34,0x00,0x00,0x00,
    01378                                            0x08,0x00,0x08,0x00,0x1b,0x2a,0x07,0x76,
    01379                                            0x01,0x1b,0x2a,0x07,0x73,0x30,0x1b,0x2a,
    01380                                            0x6d,0x00,0x14,0x01,0xf4,0x02,0x00,0x01,
    01381                                            0xf0,0x1b,0x2a,0x07,0x63};
    01382
    01383 #define LXM_Z42_STARTSIZE 0x30
    01384   /* 600 dpi */
    01385   unsigned char startHeader_z42[LXM_Z42_STARTSIZE]={0x1B,0x2A,0x81,0x00,0x1C,0x50,0x41,0x00,
    01386                                            0x01,0x00,0x58,0x02,0x04,0x00,0xC0,0x12,
    01387                                            0xC8,0x19,0x02,0x00,0x50,0x00,0x14,0x00,
    01388                                            0x07,0x00,0x08,0x00,0x1B,0x2A,0x07,0x73,
    01389                                            0x30,0x1B,0x2A,0x6D,0x00,0x14,0x01,0xC0,
    01390                                            0x02,0x00,0x01,0xBE,0x1B,0x2A,0x07,0x63};
    01391
    01392   #define ESC2a "\033\052"
    01393
    01394
    01395
    01396 #define LXM_3200_STARTSIZE 32
    01397
    01398   unsigned char startHeader_3200[LXM_3200_STARTSIZE] =
    01399   {
    01400     0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    01401     0x1b, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
    01402     0x1b, 0x30, 0x80, 0x0C, 0x02, 0x00, 0x00, 0xbe,
    01403     0x1b, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21
    01404   };
    01405
    01406   /* write init sequence */
    01407   switch(caps->model)
    01408         {
    01409                 case m_z52:
    01410                         stp_zfwrite((const char *) startHeader_z52,
    01411                                     LXM_Z52_STARTSIZE,1,v);
    01412 #ifdef DEBUG
    01413                         lex_write_tmp_file(dbgfileprn, (void *)startHeader_z52, LXM_Z52_STARTSIZE);
    01414 #endif
    01415                 case m_z42:
    01416                         stp_zfwrite((const char *) startHeader_z42,
    01417                                     LXM_Z42_STARTSIZE,1,v);
    01418 #ifdef DEBUG
    01419                         lex_write_tmp_file(dbgfileprn, (void *)startHeader_z42, LXM_Z42_STARTSIZE);
    01420 #endif
    01421                         break;
    01422
    01423                 case m_3200:
    01424                         stp_zfwrite((const char *) startHeader_3200,
    01425                                     LXM_3200_STARTSIZE, 1, v);
    01426                         break;
    01427
    01428                 default:
    01429                         stp_erprintf("Unknown printer !! %i\n", caps->model);
    01430                         return 0;
    01431   }
    01432
    01433
    01434
    01435   /*
    01436 #ifdef DEBUG
    01437   stp_erprintf("lexmark: printable size = %dx%d (%dx%d) %02x%02x %02x%02x\n",
    01438           page_width,page_height,printable_width,printable_length,
    01439           arg_70_1,arg_70_2,arg_70_3,arg_70_4);
    01440 #endif
    01441   */
    01442   return 1;
    01443 }
    01444
    01445 static void lexmark_deinit_printer(const stp_vars_t *v, const lexmark_cap_t * caps)
    01446 {
    01447
    01448         switch(caps->model)     {
    01449                 case m_z52:
    01450                 {
    01451                         char buffer[40];
    01452
    01453                         memcpy(buffer, ESC2a, 2);
    01454                         buffer[2] = 0x7;
    01455                         buffer[3] = 0x65;
    01456
    01457 #ifdef DEBUG
    01458                         stp_erprintf("lexmark: <<eject page.>> %x %x %x %x   %lx\n", buffer[0],  buffer[1], buffer[2], buffer[3], dbgfileprn);
    01459                         lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 4);
    01460 #endif
    01461                         /* eject page */
    01462                         stp_zfwrite(buffer, 1, 4, v);
    01463                 }
    01464                 break;
    01465
    01466                 case m_z42:
    01467                 {
    01468                         unsigned char buffer[12] = {0x1B,0x2A,0x07,0x65,0x1B,0x2A,0x82,0x00,0x00,0x00,0x00,0xAC};
    01469 #ifdef DEBUG
    01470                         stp_erprintf("lexmark: <<eject page.>>\n");
    01471                         lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 12);
    01472 #endif
    01473                         /* eject page */
    01474                         stp_zfwrite((char *)buffer, 1, 12, v);
    01475                 }
    01476                 break;
    01477
    01478                 case m_3200:
    01479                 {
    01480                   unsigned char buffer[24] =
    01481                   {
    01482                     0x1b, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    01483                     0x1b, 0x31, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
    01484                     0x1b, 0x33, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33
    01485                   };
    01486
    01487 #ifdef DEBUG
    01488                         stp_erprintf("Headpos: %d\n", lxm3200_headpos);
    01489 #endif
    01490
    01491                         lxm3200_linetoeject += 2400;
    01492                         buffer[3] = lxm3200_linetoeject >> 8;
    01493                         buffer[4] = lxm3200_linetoeject & 0xff;
    01494                         buffer[7] = lexmark_calc_3200_checksum(&buffer[0]);
    01495                         buffer[11] = lxm3200_headpos >> 8;
    01496                         buffer[12] = lxm3200_headpos & 0xff;
    01497                         buffer[15] = lexmark_calc_3200_checksum(&buffer[8]);
    01498
    01499                         stp_zfwrite((const char *)buffer, 24, 1, v);
    01500                 }
    01501                 break;
    01502
    01503                 case m_lex7500:
    01504                         break;
    01505         }
    01506
    01507 }
    01508
    01509
    01510 /* paper_shift() -- shift paper in printer -- units are unknown :-)
    01511  */
    01512 static void paper_shift(const stp_vars_t *v, int offset, const lexmark_cap_t * caps)
    01513 {
    01514         switch(caps->model)     {
    01515                 case m_z52:
    01516                 case m_z42:
    01517                 {
    01518                         unsigned char buf[5] = {0x1b, 0x2a, 0x3, 0x0, 0x0};
    01519                         if(offset == 0)return;
    01520                         buf[3] = (unsigned char)(offset >> 8);
    01521                         buf[4] = (unsigned char)(offset & 0xFF);
    01522                         stp_zfwrite((const char *)buf, 1, 5, v);
    01523 #ifdef DEBUG
    01524                         lex_write_tmp_file(dbgfileprn, (void *)buf, 5);
    01525 #endif
    01526                 }
    01527                 break;
    01528
    01529                 case m_3200:
    01530                 {
    01531                         unsigned char buf[8] = {0x1b, 0x23, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00};
    01532                         if(offset == 0)return;
    01533                         lxm3200_linetoeject -= offset;
    01534                         buf[3] = (unsigned char)(offset >> 8);
    01535                         buf[4] = (unsigned char)(offset & 0xff);
    01536                         buf[7] = lexmark_calc_3200_checksum(buf);
    01537                         stp_zfwrite((const char *)buf, 1, 8, v);
    01538                 }
    01539                 break;
    01540
    01541                 case m_lex7500:
    01542                         break;
    01543         }
    01544
    01545 #ifdef DEBUG
    01546         stp_erprintf("Lines to eject: %d\n", lxm3200_linetoeject);
    01547 #endif
    01548 }
    01549
    01550 /*
    01551  * 'advance_buffer()' - Move (num) lines of length (len) down one line
    01552  *                      and sets first line to 0s
    01553  *                      accepts NULL pointers as buf
    01554  *                  !!! buf must contain more than (num) lines !!!
    01555  *                      also sets first line to 0s if num<1
    01556  */
    01557 #if 0
    01558 static void
    01559 lexmark_advance_buffer(unsigned char *buf, int len, int num)
    01560 {
    01561   if (!buf || !len) return;
    01562   if (num>0) memmove(buf+len,buf,len*num);
    01563   memset(buf,0,len);
    01564 }
    01565 #endif
    01566
    01567 static double
    01568 get_double_param(stp_vars_t *v, const char *param)
    01569 {
    01570   if (param && stp_check_float_parameter(v, param, STP_PARAMETER_ACTIVE))
    01571     return stp_get_float_parameter(v, param);
    01572   else
    01573     return 1.0;
    01574 }
    01575
    01576 /**********************************************************
    01577  * lexmark_print() - Print an image to a LEXMARK printer.
    01578  **********************************************************/
    01579 /* This method should not be printer dependent (mybe it is because of nozzle count and other things) */
    01580 /* The method will set the printing method depending on the selected printer.
    01581    It will define the colors to be used and the resolution.
    01582    Additionally the pass_length will be defined.
    01583    The method lexmark_write() is responsible to handle the received lines
    01584    in a correct way.
    01585 */
    01586 static int
    01587 lexmark_do_print(stp_vars_t *v, stp_image_t *image)
    01588 {
    01589   int           status = 1;
    01590   int           y;              /* Looping vars */
    01591   int           xdpi, ydpi;     /* Resolution */
    01592   int           n;              /* Output number */
    01593   int page_width,       /* Width of page */
    01594     page_height,        /* Length of page */
    01595     page_left,
    01596     page_top,
    01597     page_right,
    01598     page_bottom,
    01599     page_true_height,   /* True length of page */
    01600     out_width,  /* Width of image on page in pixles */
    01601     out_height, /* Length of image on page */
    01602     out_channels,       /* Output bytes per pixel */
    01603     length,             /* Length of raster data in bytes*/
    01604     buf_length,     /* Length of raster data buffer (dmt) */
    01605     errdiv,             /* Error dividend */
    01606     errmod,             /* Error modulus */
    01607     errval,             /* Current error value */
    01608     errline,    /* Current raster line */
    01609     errlast;    /* Last raster line loaded */
    01610   unsigned      zero_mask;
    01611   int           image_height,
    01612                 image_width;
    01613   int           use_dmt = 0;
    01614   int pass_length=0;              /* count of inkjets for one pass */
    01615   int add_top_offset=0;              /* additional top offset */
    01616   int printMode = 0;
    01617     int source;
    01618   /* Lexmark do not have differnet pixel sizes. We have to correct the density according the print resolution. */
    01619   double  densityDivisor;            /* This parameter is will adapt the density according the resolution */
    01620   double k_lower, k_upper;
    01621   int  physical_xdpi = 0;
    01622   int  physical_ydpi = 0;
    01623   int i;
    01624
    01625   stp_curve_t *lum_adjustment = NULL;
    01626   stp_curve_t *hue_adjustment = NULL;
    01627   stp_curve_t *sat_adjustment = NULL;
    01628
    01629   /* weave parameters */
    01630   lexmark_linebufs_t cols;
    01631   int  nozzle_separation;
    01632   int  horizontal_passes;
    01633   int  ncolors;
    01634   lexm_privdata_weave privdata;
    01635
    01636   lexmark_lineoff_t lineoff_buffer;  /* holds the line offsets of each color */
    01637 #ifdef DEBUG
    01638   testdata td;
    01639 #endif
    01640
    01641
    01642   int           model         = stp_get_model_id(v);
    01643   const char    *resolution   = stp_get_string_parameter(v, "Resolution");
    01644   const char    *media_type   = stp_get_string_parameter(v, "MediaType");
    01645   const char    *media_source = stp_get_string_parameter(v, "InputSlot");
    01646   const char    *print_mode = stp_get_string_parameter(v, "PrintingMode");
    01647   int printing_color = 0;
    01648   const char    *ink_type     = stp_get_string_parameter(v, "InkType");
    01649   int           top = stp_get_top(v);
    01650   int           left = stp_get_left(v);
    01651
    01652   const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
    01653   const lexmark_res_t *res_para_ptr =
    01654     lexmark_get_resolution_para(model, resolution);
    01655   const paper_t *media = get_media_type(media_type,caps);
    01656   const lexmark_inkparam_t *ink_parameter;
    01657
    01658   stp_prune_inactive_options(v);
    01659
    01660 #ifdef DEBUG
    01661   dbgfileprn = lex_open_tmp_file(); /* open file with xx */
    01662 #endif
    01663
    01664   if (!stp_verify(v))
    01665     {
    01666       stp_eprintf(v, "Print options not verified; cannot print.\n");
    01667       return 0;
    01668     }
    01669   if (strcmp(print_mode, "Color") == 0)
    01670     printing_color = 1;
    01671
    01672   ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
    01673
    01674   if (ink_parameter == NULL)
    01675     {
    01676       stp_eprintf(v, "Illegal Ink Type specified; cannot print.\n");
    01677       return 0;
    01678     }
    01679
    01680   stp_image_init(image);
    01681
    01682   source= lexmark_source_type(media_source,caps);
    01683
    01684   /* force grayscale if image is grayscale
    01685    *                 or single black cartridge installed
    01686    */
    01687
    01688   if ((ink_parameter->used_colors == COLOR_MODE_K) ||
    01689       (caps->inks == LEXMARK_INK_K))
    01690     {
    01691       printing_color = 0;
    01692       stp_set_string_parameter(v, "PrintingMode", "BW");
    01693     }
    01694
    01695   /*
    01696    * Choose the correct color conversion function...
    01697    */
    01698
    01699
    01700   ncolors = ink_parameter->ncolors;
    01701   printMode = ink_parameter->used_colors;
    01702   pass_length = ink_parameter->pass_length;
    01703   add_top_offset = ink_parameter->v_top_head_offset;
    01704
    01705
    01706   /*
    01707    * Figure out the output resolution...
    01708    */
    01709
    01710   stp_describe_resolution(v, &xdpi, &ydpi);
    01711 #ifdef DEBUG
    01712   stp_erprintf("lexmark: resolution=%dx%d\n",xdpi,ydpi);
    01713 #endif
    01714
    01715   switch (res_para_ptr->resid) {
    01716   case DPI300:
    01717     physical_xdpi = 300;
    01718     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
    01719     break;
    01720   case DPI600:
    01721     physical_xdpi = 600;
    01722     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
    01723     break;
    01724   case DPI1200:
    01725   case DPItest:
    01726     physical_xdpi = 1200;
    01727     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
    01728     break;
    01729   default:
    01730     return 0;
    01731     break;
    01732   }
    01733   /* adapt the density */
    01734   densityDivisor = ((xdpi / 300)*(ydpi/ 600));
    01735
    01736 #ifdef DEBUG
    01737   if (res_para_ptr->resid == DPItest) {
    01738     stp_erprintf("Start test print1\n");
    01739     doTestPrint = 1;
    01740   }
    01741 #endif
    01742
    01743   if ((printMode & COLOR_MODE_PHOTO) == COLOR_MODE_PHOTO) {
    01744     /* in case of photo mode we have to go a bit ligther */
    01745 densityDivisor /= 1.2;
    01746   }
    01747
    01748   nozzle_separation = ydpi / physical_ydpi;
    01749
    01750   horizontal_passes = xdpi / physical_xdpi;
    01751 #ifdef DEBUG
    01752   stp_erprintf("lexmark: horizontal_passes %i, xdpi %i, physical_xdpi %i\n",
    01753                horizontal_passes, xdpi, physical_xdpi);
    01754 #endif
    01755
    01756
    01757
    01758
    01759   if (!strcmp(resolution+(strlen(resolution)-3),"DMT") &&
    01760       (caps->features & LEXMARK_CAP_DMT)) {
    01761     use_dmt= 1;
    01762 #ifdef DEBUG
    01763     stpi_erprintf("lexmark: using drop modulation technology\n");
    01764 #endif
    01765   }
    01766
    01767   /*
    01768   * Compute the output size...
    01769   */
    01770
    01771   out_width = stp_get_width(v);
    01772   out_height = stp_get_height(v);
    01773
    01774   internal_imageable_area(v, 0, &page_left, &page_right,
    01775                           &page_bottom, &page_top);
    01776   left -= page_left;
    01777   top -= page_top;
    01778   page_width = page_right - page_left;
    01779   page_height = page_bottom - page_top;
    01780
    01781 #ifdef DEBUG
    01782   stp_erprintf("page_right %d, page_left %d, page_top %d, page_bottom %d, left %d, top %d\n",page_right, page_left, page_top, page_bottom,left, top);
    01783 #endif
    01784
    01785   image_height = stp_image_height(image);
    01786   image_width = stp_image_width(image);
    01787
    01788   stp_default_media_size(v, &n, &page_true_height);
    01789   lxm3200_linetoeject = (page_true_height * 1200) / 72;
    01790
    01791
    01792   if (!lexmark_init_printer(v, caps, printing_color,
    01793                             media_source,
    01794                             xdpi, ydpi, page_width, page_height,
    01795                             top,left,use_dmt))
    01796     return 0;
    01797
    01798   /*
    01799   * Convert image size to printer resolution...
    01800   */
    01801
    01802   out_width  = xdpi * out_width / 72;
    01803   out_height = ydpi * out_height / 72;
    01804
    01805 #ifdef DEBUG
    01806
    01807   stp_erprintf("border: left %ld, x_raster_res %d, offser_left %ld\n", left, caps->x_raster_res, caps->offset_left_border);
    01808 #endif
    01809
    01810   left = ((caps->x_raster_res * left) / 72) + caps->offset_left_border;
    01811
    01812 #ifdef DEBUG
    01813   stp_erprintf("border: left %d\n", left);
    01814 #endif
    01815
    01816
    01817
    01818 #ifdef DEBUG
    01819   if (doTestPrint == 1) {
    01820     stp_erprintf("Start test print\n");
    01821     testprint(&td);
    01822     out_width = td.x;
    01823     out_height = td.y;
    01824     if (td.cols != 7) {
    01825     printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y;
    01826     } else {
    01827     printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_LM | COLOR_MODE_LC;
    01828     }
    01829   }
    01830 #endif
    01831
    01832  /*
    01833   * Allocate memory for the raster data...
    01834   */
    01835
    01836   length = (out_width + 7) / 8;
    01837
    01838
    01839
    01840   if (use_dmt) {
    01841     /*    buf_length= length*2; */
    01842     buf_length= length;
    01843   } else {
    01844     buf_length= length;
    01845   }
    01846
    01847 #ifdef DEBUG
    01848   stp_erprintf("lexmark: buflength is %d!\n",buf_length);
    01849 #endif
    01850
    01851
    01852   /* Now we know the color which are used, let's get the memory for every color image */
    01853   cols.p.k = NULL;
    01854   cols.p.c = NULL;
    01855   cols.p.y = NULL;
    01856   cols.p.m = NULL;
    01857   cols.p.C = NULL;
    01858   cols.p.M = NULL;
    01859   cols.p.Y = NULL;
    01860
    01861
    01862   if ((printMode & COLOR_MODE_C) == COLOR_MODE_C) {
    01863     cols.p.c = stp_zalloc(buf_length+10);
    01864   }
    01865   if ((printMode & COLOR_MODE_Y) == COLOR_MODE_Y) {
    01866     cols.p.y = stp_zalloc(buf_length+10);
    01867   }
    01868   if ((printMode & COLOR_MODE_M) == COLOR_MODE_M) {
    01869     cols.p.m = stp_zalloc(buf_length+10);
    01870   }
    01871   if ((printMode & COLOR_MODE_K) == COLOR_MODE_K) {
    01872     cols.p.k = stp_zalloc(buf_length+10);
    01873   }
    01874   if ((printMode & COLOR_MODE_LC) == COLOR_MODE_LC) {
    01875     cols.p.C = stp_zalloc(buf_length+10);
    01876   }
    01877   if ((printMode & COLOR_MODE_LY) == COLOR_MODE_LY) {
    01878     cols.p.Y = stp_zalloc(buf_length+10);
    01879   }
    01880   if ((printMode & COLOR_MODE_LM) == COLOR_MODE_LM) {
    01881     cols.p.M = stp_zalloc(buf_length+10);
    01882   }
    01883
    01884   if (cols.p.k)
    01885     {
    01886       if (cols.p.c)
    01887         stp_set_string_parameter(v, "STPIOutputType", "KCMY");
    01888       else
    01889         stp_set_string_parameter(v, "STPIOutputType", "Grayscale");
    01890     }
    01891   else
    01892     stp_set_string_parameter(v, "STPIOutputType", "CMY");
    01893
    01894 #ifdef DEBUG
    01895   stp_erprintf("lexmark: driver will use colors ");
    01896   if (cols.p.c)     stp_erputc('c');
    01897   if (cols.p.C)     stp_erputc('C');
    01898   if (cols.p.m)     stp_erputc('m');
    01899   if (cols.p.M)     stp_erputc('M');
    01900   if (cols.p.y)     stp_erputc('y');
    01901   if (cols.p.Y)     stp_erputc('Y');
    01902   if (cols.p.k)     stp_erputc('k');
    01903   stp_erprintf("\n");
    01904 #endif
    01905
    01906   /* initialize soft weaveing */
    01907   privdata.ink_parameter = ink_parameter;
    01908   privdata.bidirectional = lexmark_print_bidirectional(model, resolution);
    01909   privdata.outbuf = stp_malloc((((((pass_length/8)*11))+40) * out_width)+2000);
    01910   privdata.direction = 0;
    01911   stp_allocate_component_data(v, "Driver", NULL, NULL, &privdata);
    01912   /*  lxm_nozzles_used = 1;*/
    01913
    01914   stp_initialize_weave(v,
    01915                        pass_length, /* jets */
    01916                        nozzle_separation, /* separation */
    01917                        horizontal_passes, /* h overample */
    01918                        res_para_ptr->vertical_passes, /* v passes */
    01919                        res_para_ptr->vertical_oversample, /* v oversample */
    01920                        ncolors, /* colors */
    01921                        1, /* bits/pixel */
    01922                        out_width, /* line width */
    01923                        out_height,
    01924                        ((top * ydpi) / 72)+(((caps->offset_top_border+add_top_offset)*ydpi)
    01925                                             /caps->y_raster_res),
    01926                        (page_height * ydpi) / 72,
    01927                        (const int *) lexmark_head_offset(ydpi, ink_type, caps, ink_parameter, &lineoff_buffer),
    01928                        STP_WEAVE_ZIGZAG, /* weave_strategy */
    01929                        flush_pass,
    01930                        stp_fill_uncompressed,  /* fill_start */
    01931                        stp_pack_uncompressed,  /* pack */
    01932                        stp_compute_uncompressed_linewidth);  /* compute_linewidth */
    01933   privdata.last_pass_offset = 0;
    01934   privdata.jets = pass_length;
    01935   privdata.ncolors = ncolors;
    01936   privdata.horizontal_weave = horizontal_passes;
    01937
    01938
    01939   if (!stp_check_float_parameter(v, "Density", STP_PARAMETER_DEFAULTED))
    01940     {
    01941       stp_set_float_parameter_active(v, "Density", STP_PARAMETER_ACTIVE);
    01942       stp_set_float_parameter(v, "Density", 1.0);
    01943     }
    01944
    01945 #ifdef DEBUG
    01946   stp_erprintf("density is %f\n",stp_get_parameter(v, "Density"));
    01947 #endif
    01948
    01949 #ifdef DEBUG
    01950   stp_erprintf("density is %f and will be changed to %f  (%f)\n",
    01951                 stp_get_float_parameter(v, "Density"),
    01952                 stp_get_float_parameter(v, "Density") / densityDivisor,
    01953                 densityDivisor);
    01954 #endif
    01955
    01956   /* Lexmark do not have differnet pixel sizes. We have to correct the density according the print resolution. */
    01957   stp_scale_float_parameter(v, "Density", 1.0 / densityDivisor);
    01958
    01959
    01960   /*
    01961    * Compute the LUT.  For now, it's 8 bit, but that may eventually
    01962    * sometimes change.
    01963    */
    01964   if (ncolors > 4)
    01965     k_lower = .5;
    01966   else
    01967     k_lower = .25;
    01968
    01969   if (media)
    01970     {
    01971       stp_scale_float_parameter(v, "Density", media->base_density);
    01972       stp_scale_float_parameter(v, "Cyan", media->p_cyan);
    01973       stp_scale_float_parameter(v, "Magenta", media->p_magenta);
    01974       stp_scale_float_parameter(v, "Yellow", media->p_yellow);
    01975       k_lower *= media->k_lower_scale;
    01976       k_upper  = media->k_upper;
    01977     }
    01978   else
    01979     {
    01980       stp_scale_float_parameter(v, "Density", .8);
    01981       k_lower *= .1;
    01982       k_upper = .5;
    01983     }
    01984   if (stp_get_float_parameter(v, "Density") > 1.0)
    01985     stp_set_float_parameter(v, "Density", 1.0);
    01986
    01987 #ifdef DEBUG
    01988   stp_erprintf("density is %f\n",stp_get_float_parameter(v, "Density"));
    01989 #endif
    01990
    01991
    01992   if (!stp_check_float_parameter(v, "GCRLower", STP_PARAMETER_ACTIVE))
    01993     stp_set_default_float_parameter(v, "GCRLower", k_lower);
    01994   if (!stp_check_float_parameter(v, "GCRUpper", STP_PARAMETER_ACTIVE))
    01995     stp_set_default_float_parameter(v, "GCRUpper", k_upper);
    01996   stp_dither_init(v, image, out_width, xdpi, ydpi);
    01997
    01998         /*
    01999           stpi_dither_set_black_lower(dither, .8 / ((1 << (use_dmt+1)) - 1));*/
    02000   /*stpi_dither_set_black_levels(dither, 0.5, 0.5, 0.5);
    02001     stpi_dither_set_black_lower(dither, 0.4);*/
    02002   /*
    02003     if (use_glossy_film)
    02004   */
    02005
    02006   if (!use_dmt) {
    02007     if (cols.p.C)
    02008       {
    02009         stp_dither_set_inks_full(v, STP_ECOLOR_C, 2, photo_dither_shades, 1.0,
    02010                                   0.31 / .5);
    02011       }
    02012     if (cols.p.M)
    02013       {
    02014         stp_dither_set_inks_full(v, STP_ECOLOR_M, 2, photo_dither_shades, 1.0,
    02015                                   0.61 / .97);
    02016       }
    02017     if (cols.p.Y)
    02018       {
    02019         stp_dither_set_inks_full(v, STP_ECOLOR_Y, 2, photo_dither_shades, 1.0,
    02020                                   0.08);
    02021       }
    02022   }
    02023
    02024   stp_channel_set_density_adjustment(v, STP_ECOLOR_K, 0,
    02025                                      get_double_param(v, "BlackDensity") *
    02026                                      get_double_param(v, "Density"));
    02027   stp_channel_set_density_adjustment(v, STP_ECOLOR_C, 0,
    02028                                      get_double_param(v, "CyanDensity") *
    02029                                      get_double_param(v, "Density"));
    02030   stp_channel_set_density_adjustment(v, STP_ECOLOR_M, 0,
    02031                                      get_double_param(v, "MagentaDensity") *
    02032                                      get_double_param(v, "Density"));
    02033   stp_channel_set_density_adjustment(v, STP_ECOLOR_Y, 0,
    02034                                      get_double_param(v, "YellowDensity") *
    02035                                      get_double_param(v, "Density"));
    02036   if (!use_dmt) {
    02037     if (cols.p.C)
    02038       {
    02039         stp_channel_set_density_adjustment
    02040           (v, STP_ECOLOR_C, 1, (get_double_param(v, "CyanDensity") *
    02041                             get_double_param(v, "LightCyanTransition") *
    02042                             get_double_param(v, "Density")));
    02043       }
    02044     if (cols.p.M)
    02045       {
    02046         stp_channel_set_density_adjustment
    02047           (v, STP_ECOLOR_M, 1, (get_double_param(v, "MagentaDensity") *
    02048                             get_double_param(v, "LightMagentaTransition") *
    02049                             get_double_param(v, "Density")));
    02050       }
    02051     if (cols.p.Y)
    02052       {
    02053         stp_channel_set_density_adjustment
    02054           (v, STP_ECOLOR_Y, 1, (get_double_param(v, "YellowDensity") *
    02055                             get_double_param(v, "LightYellowTransition") *
    02056                             get_double_param(v, "Density")));
    02057       }
    02058   }
    02059
    02060   /*
    02061    * Output the page...
    02062   */
    02063
    02064   if (!stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_ACTIVE) &&
    02065       media->hue_adjustment)
    02066     {
    02067       hue_adjustment = stp_read_and_compose_curves
    02068         (lexmark_hue_adjustment(caps, v),
    02069          media ? media->hue_adjustment : NULL, STP_CURVE_COMPOSE_ADD, 384);
    02070       stp_set_curve_parameter(v, "HueMap", hue_adjustment);
    02071       stp_curve_destroy(hue_adjustment);
    02072     }
    02073   if (!stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_ACTIVE) &&
    02074       media->lum_adjustment)
    02075     {
    02076       lum_adjustment = stp_read_and_compose_curves
    02077         (lexmark_lum_adjustment(caps, v),
    02078          media ? media->lum_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
    02079       stp_set_curve_parameter(v, "LumMap", lum_adjustment);
    02080       stp_curve_destroy(lum_adjustment);
    02081     }
    02082   if (!stp_check_curve_parameter(v, "SatMap", STP_PARAMETER_ACTIVE) &&
    02083       media->sat_adjustment)
    02084     {
    02085       sat_adjustment = stp_read_and_compose_curves
    02086         (lexmark_sat_adjustment(caps, v),
    02087          media ? media->sat_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
    02088       stp_set_curve_parameter(v, "SatMap", sat_adjustment);
    02089       stp_curve_destroy(sat_adjustment);
    02090     }
    02091
    02092   out_channels = stp_color_init(v, image, 65536);
    02093
    02094   /* calculate the memory we need for one line of the printer image (hopefully we are right) */
    02095 #ifdef DEBUG
    02096   stp_erprintf("---------- buffer mem size = %d\n", (((((pass_length/8)*11)/10)+40) * out_width)+200);
    02097 #endif
    02098
    02099   errdiv  = image_height / out_height;
    02100   errmod  = image_height % out_height;
    02101   errval  = 0;
    02102   errlast = -1;
    02103   errline  = 0;
    02104
    02105   if (cols.p.k)
    02106     stp_dither_add_channel(v, cols.p.k, STP_ECOLOR_K, 0);
    02107   if (cols.p.c)
    02108     stp_dither_add_channel(v, cols.p.c, STP_ECOLOR_C, 0);
    02109   if (cols.p.C)
    02110     stp_dither_add_channel(v, cols.p.C, STP_ECOLOR_C, 1);
    02111   if (cols.p.m)
    02112     stp_dither_add_channel(v, cols.p.m, STP_ECOLOR_M, 0);
    02113   if (cols.p.M)
    02114     stp_dither_add_channel(v, cols.p.M, STP_ECOLOR_M, 1);
    02115   if (cols.p.y)
    02116     stp_dither_add_channel(v, cols.p.y, STP_ECOLOR_Y, 0);
    02117   if (cols.p.Y)
    02118     stp_dither_add_channel(v, cols.p.Y, STP_ECOLOR_Y, 1);
    02119   privdata.hoffset = left;
    02120   privdata.ydpi = ydpi;
    02121   privdata.model = model;
    02122   privdata.width = out_width;
    02123   privdata.xdpi = xdpi;
    02124   privdata.physical_xdpi = physical_xdpi;
    02125
    02126   for (y = 0; y < out_height; y ++)
    02127     {
    02128       int duplicate_line = 1;
    02129
    02130       if (errline != errlast)
    02131         {
    02132           errlast = errline;
    02133           duplicate_line = 0;
    02134           if (stp_color_get_row(v, image, errline, &zero_mask))
    02135             {
    02136               status = 2;
    02137               break;
    02138             }
    02139         }
    02140       stp_dither(v, y, duplicate_line, zero_mask, NULL);
    02141       stp_write_weave(v, (unsigned char **)cols.v);
    02142
    02143       errval += errmod;
    02144       errline += errdiv;
    02145       if (errval >= out_height)
    02146         {
    02147           errval -= out_height;
    02148           errline ++;
    02149         }
    02150     }
    02151   stp_image_conclude(image);
    02152
    02153   stp_flush_all(v);
    02154
    02155   lexmark_deinit_printer(v, caps);
    02156
    02157   /*
    02158   * Cleanup...
    02159   */
    02160   if (privdata.outbuf != NULL) {
    02161     stp_free(privdata.outbuf);/* !!!!!!!!!!!!!! */
    02162   }
    02163
    02164   for (i = 0; i < NCHANNELS; i++)
    02165     if (cols.v[i])
    02166       stp_free(cols.v[i]);
    02167
    02168 #ifdef DEBUG
    02169   lex_tmp_file_deinit(dbgfileprn);
    02170 #endif
    02171
    02172   return status;
    02173 }
    02174
    02175 static int
    02176 lexmark_print(const stp_vars_t *v, stp_image_t *image)
    02177 {
    02178   int status;
    02179   stp_vars_t *nv = stp_vars_create_copy(v);
    02180   stp_prune_inactive_options(nv);
    02181   status = lexmark_do_print(nv, image);
    02182   stp_vars_destroy(nv);
    02183   return status;
    02184 }
    02185
    02186 static const stp_printfuncs_t print_lexmark_printfuncs =
    02187 {
    02188   lexmark_list_parameters,
    02189   lexmark_parameters,
    02190   stp_default_media_size,
    02191   lexmark_imageable_area,
    02192   lexmark_limit,
    02193   lexmark_print,
    02194   lexmark_describe_resolution,
    02195   lexmark_describe_output,
    02196   stp_verify_printer_params,
    02197   NULL,
    02198   NULL
    02199 };
    02200
    02201
    02202
    02203 /* lexmark_init_line
    02204    This method is printer type dependent code.
    02205
    02206    This method initializes the line to be printed. It will set
    02207    the printer specific initialization which has to be done bofor
    02208    the pixels of the image could be printed.
    02209 */
    02210 static unsigned char *
    02211 lexmark_init_line(int mode, unsigned char *prnBuf,
    02212                   int pass_length,
    02213                   int offset,    /* offset from left in 1/"x_raster_res" DIP (printer resolution)*/
    02214                   int width, int direction,
    02215                   const lexmark_inkparam_t *ink_parameter,
    02216                   const lexmark_cap_t *   caps          /* I - Printer model */
    02217                   )
    02218 {
    02219   int pos1 = 0;
    02220   int pos2 = 0;
    02221   int abspos, disp;
    02222   int hend = 0;
    02223   int header_size = 0;
    02224
    02225
    02226   /*  stp_erprintf("#### width %d, length %d, pass_length %d\n", width, length, pass_length);*/
    02227   /* first, we wirte the line header */
    02228   switch(caps->model)  {
    02229   case m_z52:
    02230   case m_z42:
    02231     if (caps->model == m_z52)
    02232       {
    02233         header_size = LXM_Z52_HEADERSIZE;
    02234         memcpy(prnBuf, outbufHeader_z52, header_size);
    02235       }
    02236     if (caps->model == m_z42)
    02237       {
    02238         header_size = LXM_Z42_HEADERSIZE;
    02239         memcpy(prnBuf, outbufHeader_z42, LXM_Z42_HEADERSIZE);
    02240       }
    02241
    02242     /* K could only be present if black is printed only. */
    02243     if ((mode & COLOR_MODE_K) || (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM))) {
    02244 #ifdef DEBUG
    02245       stp_erprintf("set  photo/black catridge \n");
    02246 #endif
    02247       prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_BLACK_PRINT;
    02248
    02249       if (direction) {
    02250       } else {
    02251         offset += ink_parameter->h_direction_offset;
    02252       }
    02253     } else {
    02254 #ifdef DEBUG
    02255       stp_erprintf("set color cartridge \n");
    02256 #endif
    02257       prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_COLOR_PRINT;
    02258
    02259       if (direction) {
    02260         offset += ink_parameter->h_catridge_offset;
    02261       } else {
    02262         offset += ink_parameter->h_catridge_offset + ink_parameter->h_direction_offset;
    02263       }
    02264     }
    02265
    02266     switch (mode & PRINT_MODE_MASK) {
    02267     case PRINT_MODE_300:
    02268       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_300_DPI;
    02269       break;
    02270     case PRINT_MODE_600:
    02271       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_600_DPI;
    02272       break;
    02273     case PRINT_MODE_1200:
    02274       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_1200_DPI;
    02275       break;
    02276     case PRINT_MODE_2400:
    02277       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_2400_DPI;
    02278       break;
    02279     }
    02280
    02281
    02282     if (direction) {
    02283       prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 1;
    02284     } else {
    02285       prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 2;
    02286     }
    02287
    02288     /* set package count */
    02289     prnBuf[13] = (unsigned char)((width) >> 8);
    02290     prnBuf[14] = (unsigned char)((width) & 0xFF);
    02291     /* set horizontal offset */
    02292     prnBuf[15] =(unsigned char)(offset >> 8);
    02293     prnBuf[16] =(unsigned char)(offset & 0xFF);
    02294
    02295     if (caps->model == m_z42) {
    02296         switch(mode & PRINT_MODE_MASK) {
    02297         case PRINT_MODE_300:
    02298                 hend = (width-1)*(2400/300);
    02299                 break;
    02300         case PRINT_MODE_600:
    02301                 hend = (width-1)*(2400/600);
    02302                 break;
    02303         case PRINT_MODE_1200:
    02304                 hend = (width-1)*(2400/1200);
    02305                 break;
    02306         case PRINT_MODE_2400:
    02307                 hend = (width-1)*(2400/2400);
    02308                 break;
    02309         }
    02310         hend += offset;
    02311         prnBuf[17] = (unsigned char)(hend >> 8);
    02312         prnBuf[18] = (unsigned char)(hend & 0xFF);
    02313
    02314         prnBuf[10] = (pass_length==208 ? 0x1A : 0x18);
    02315     }
    02316
    02317     return prnBuf + header_size;  /* return the position where the pixels have to be written */
    02318     break;
    02319     case m_3200:
    02320       memcpy(prnBuf, outbufHeader_3200, LXM_3200_HEADERSIZE);
    02321
    02322       offset = (offset - 60) * 4;
    02323
    02324       /* K could only be present if black is printed only. */
    02325       if((mode & COLOR_MODE_K) ||
    02326          (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM)))
    02327         {
    02328           disp = LXM3200_LEFTOFFS;
    02329           prnBuf[2] = 0x00;
    02330         }
    02331       else
    02332         {
    02333           disp = LXM3200_RIGHTOFFS;
    02334           prnBuf[2] = 0x80;
    02335         }
    02336
    02337       if(pass_length == 208)
    02338         {
    02339           prnBuf[2] |= 0x10;
    02340         }
    02341
    02342       switch(mode & PRINT_MODE_MASK)    {
    02343         case PRINT_MODE_300:
    02344           prnBuf[2] |= 0x20;
    02345           pos1 = offset + disp;
    02346           pos2 = offset + (width * 4) + disp;
    02347           break;
    02348
    02349         case PRINT_MODE_600:
    02350           prnBuf[2] |= 0x00;
    02351           pos1 = offset + disp;
    02352           pos2 = offset + (width * 2) + disp;
    02353           break;
    02354
    02355         case PRINT_MODE_1200:
    02356           prnBuf[2] |= 0x40;
    02357           pos1 = offset + disp;
    02358           pos2 = (offset + width) + disp;
    02359           break;
    02360         }
    02361
    02362       if(direction)
    02363         prnBuf[2] |= 0x01;
    02364       else
    02365         prnBuf[2] |= 0x00;
    02366
    02367       /* set package count */
    02368       prnBuf[3] = (unsigned char)((width) >> 8);
    02369       prnBuf[4] = (unsigned char)((width) & 0xff);
    02370
    02371       /* set horizontal offset */
    02372       prnBuf[21] = (unsigned char)(pos1 >> 8);
    02373       prnBuf[22] = (unsigned char)(pos1 & 0xFF);
    02374
    02375       abspos = ((((pos2 - 3600) >> 3) & 0xfff0) + 9);
    02376       prnBuf[5] = (abspos-lxm3200_headpos) >> 8;
    02377       prnBuf[6] = (abspos-lxm3200_headpos) & 0xff;
    02378
    02379       lxm3200_headpos = abspos;
    02380
    02381       if(LXM3200_RIGHTOFFS > 4816)
    02382         abspos = (((LXM3200_RIGHTOFFS - 4800) >> 3) & 0xfff0);
    02383       else
    02384         abspos = (((LXM3200_RIGHTOFFS - 3600) >> 3) & 0xfff0);
    02385
    02386       prnBuf[11] = (lxm3200_headpos-abspos) >> 8;
    02387       prnBuf[12] = (lxm3200_headpos-abspos) & 0xff;
    02388
    02389       lxm3200_headpos = abspos;
    02390
    02391       prnBuf[7] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[0]);
    02392       prnBuf[15] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[8]);
    02393       prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
    02394
    02395       /* return the position where the pixels have to be written */
    02396       return prnBuf + LXM_3200_HEADERSIZE;
    02397       break;
    02398
    02399   case m_lex7500:
    02400     stp_erprintf("Lexmark 7500 not supported !\n");
    02401     return NULL;
    02402     break;
    02403   }
    02404   return NULL;
    02405 }
    02406
    02407
    02408 typedef struct Lexmark_head_colors {
    02409   int v_start;
    02410   unsigned char *line;
    02411   int head_nozzle_start;
    02412   int head_nozzle_end;
    02413   int used_jets;
    02414 } Lexmark_head_colors;
    02415
    02416 /* lexmark_write
    02417    This method is has NO printer type dependent code.
    02418    This method writes a single line of the print. The line consits of "pass_length"
    02419    pixel lines (pixels, which could be printed with one pass by the printer.
    02420 */
    02421
    02422
    02423 static int
    02424 lexmark_write(const stp_vars_t *v,              /* I - Print file or command */
    02425               unsigned char *prnBuf,      /* mem block to buffer output */
    02426               int *paperShift,
    02427               int direction,
    02428               int pass_length,       /* num of inks to print */
    02429               const lexmark_cap_t *   caps,             /* I - Printer model */
    02430               const lexmark_inkparam_t *ink_parameter,
    02431               int xdpi,
    02432               int yCount,
    02433               Lexmark_head_colors *head_colors,
    02434               int           length,     /* I - Length of bitmap data in bytes */
    02435               int           mode,       /* I - Which color */
    02436               int           ydpi,               /* I - Vertical resolution */
    02437               int           width,      /* I - Printed width in pixles */
    02438               int           offset,     /* I - Offset from left side in lexmark_cap_t.x_raster_res DPI */
    02439               int           dmt)
    02440 {
    02441   unsigned char *tbits=NULL, *p=NULL;
    02442   int clen;
    02443   int x;  /* actual vertical position */
    02444   int y;  /* actual horizontal position */
    02445   int dy; /* horiz. inkjet posintion */
    02446   int x1;
    02447   unsigned short pixelline;  /* byte to be written */
    02448   unsigned int valid_bytes; /* bit list which tells the present bytes */
    02449   int xStart=0; /* count start for horizontal line */
    02450   int xEnd=0;
    02451   int xIter=0;  /* count direction for horizontal line */
    02452   int anyCol=0;
    02453   int colIndex;
    02454   int rwidth; /* real with used at printing (includes shift between even & odd nozzles) */
    02455 #ifdef DEBUG
    02456   /* stp_erprintf("<%c>",("CMYKcmy"[coloridx])); */
    02457   stp_erprintf("pass length %d\n", pass_length);
    02458 #endif
    02459
    02460
    02461   /* first, we check the length of the line an cut it if necessary. */
    02462   if ((((width*caps->x_raster_res)/xdpi)+offset) > ((caps->max_paper_width*caps->x_raster_res)/72)) {
    02463     /* line too long !! Cut the line */
    02464 #ifdef DEBUG
    02465    stp_erprintf("!! Line too long !! reduce it from %d", width);
    02466 #endif
    02467     width = ((((caps->max_paper_width*caps->x_raster_res)/72) - offset)*xdpi)/caps->x_raster_res;
    02468 #ifdef DEBUG
    02469    stp_erprintf(" down to %d\n", width);
    02470 #endif
    02471   }
    02472
    02473
    02474   /* we have to write the initial sequence for a line */
    02475
    02476 #ifdef DEBUG
    02477   stp_erprintf("lexmark: printer line initialized.\n");
    02478 #endif
    02479
    02480   if (direction) {
    02481     /* left to right */
    02482     xStart = -get_lr_shift(mode);
    02483     xEnd = width-1;
    02484     xIter = 1;
    02485     rwidth = xEnd - xStart;
    02486   } else {
    02487     /* right to left ! */
    02488     xStart = width-1;
    02489     xEnd = -get_lr_shift(mode);
    02490     rwidth = xStart - xEnd;
    02491     xIter = -1;
    02492   }
    02493
    02494   p = lexmark_init_line(mode, prnBuf, pass_length, offset, rwidth,
    02495                         direction,  /* direction */
    02496                         ink_parameter, caps);
    02497
    02498
    02499 #ifdef DEBUG
    02500   stp_erprintf("lexmark: xStart %d, xEnd %d, xIter %d.\n", xStart, xEnd, xIter);
    02501 #endif
    02502
    02503   /* now we can start to write the pixels */
    02504   yCount = 2;
    02505
    02506
    02507   for (x=xStart; x != xEnd; x+=xIter) {
    02508     int  anyDots=0; /* tells us if there was any dot to print */
    02509
    02510        switch(caps->model)      {
    02511         case m_z52:
    02512           tbits = p;
    02513           *(p++) = 0x3F;
    02514           tbits[1] = 0; /* here will be nice bitmap */
    02515           p++;
    02516           break;
    02517
    02518         case m_3200:
    02519         case m_z42:
    02520           tbits = p;
    02521           p += 4;
    02522           break;
    02523
    02524         case m_lex7500:
    02525           break;
    02526         }
    02527
    02528
    02529     pixelline =0;     /* here we store 16 pixels */
    02530     valid_bytes = 0;  /* for every valid word (16 bits) a corresponding bit will be set to 1. */
    02531
    02532     anyDots =0;
    02533     x1 = x+get_lr_shift(mode);
    02534
    02535     for (colIndex=0; colIndex < 3; colIndex++) {
    02536       for (dy=head_colors[colIndex].head_nozzle_start,y=head_colors[colIndex].v_start*yCount;
    02537            (dy < head_colors[colIndex].head_nozzle_end);
    02538            y+=yCount, dy++) { /* we start counting with 1 !!!! */
    02539         if (head_colors[colIndex].line != NULL) {
    02540           pixelline = pixelline << 1;
    02541           if ((x >= 0) &&
    02542               ((dy - head_colors[colIndex].head_nozzle_start) < (head_colors[colIndex].used_jets/2)))
    02543             pixelline = pixelline | ((head_colors[colIndex].line[(y*length)+(x/8)] >> (7-(x%8))) & 0x1);
    02544           pixelline = pixelline << 1;
    02545           if ((x1 < width) &&
    02546               (((dy - head_colors[colIndex].head_nozzle_start)+1) < (head_colors[colIndex].used_jets/2)))
    02547             pixelline = pixelline | ((head_colors[colIndex].line[(((yCount>>1)+y)*length)+ (x1/8)] >> (7-(x1%8))) & 0x1);
    02548
    02549         } else {
    02550           pixelline = pixelline << 2;
    02551         }
    02552         switch(caps->model)             {
    02553         case m_z52:
    02554           if ((dy%8) == 7) {
    02555             /* we have two bytes, write them */
    02556             anyDots |= pixelline;
    02557             if (pixelline) {
    02558               /* we have some dots */
    02559               valid_bytes = valid_bytes >> 1;
    02560               *((p++)) = (unsigned char)(pixelline >> 8);
    02561               *((p++)) = (unsigned char)(pixelline & 0xff);
    02562             } else {
    02563               /* there are no dots ! */
    02564               valid_bytes = valid_bytes >> 1;
    02565               valid_bytes |= 0x1000;
    02566             }
    02567             pixelline =0;
    02568           }
    02569           break;
    02570
    02571         case m_3200:
    02572         case m_z42:
    02573           if((dy % 4) == 3)
    02574             {
    02575               anyDots |= pixelline;
    02576               valid_bytes <<= 1;
    02577
    02578               if(pixelline)
    02579                 *(p++) = (unsigned char)(pixelline & 0xff);
    02580               else
    02581                 valid_bytes |= 0x01;
    02582
    02583               pixelline = 0;
    02584             }
    02585           break;
    02586
    02587         case m_lex7500:
    02588           break;
    02589         }
    02590       }
    02591     }
    02592
    02593     switch(caps->model) {
    02594     case m_z52:
    02595       if (pass_length != 208) {
    02596         valid_bytes = valid_bytes >> 1;
    02597         valid_bytes |= 0x1000;
    02598       }
    02599       tbits[0] = 0x20 | ((unsigned char)((valid_bytes >> 8) & 0x1f));
    02600       tbits[1] = (unsigned char)(valid_bytes & 0xff);
    02601       break;
    02602
    02603     case m_z42:
    02604       if ((p-tbits) & 1) *(p++)=0; /* z42 packets always have even length */
    02605       /* fall through */
    02606     case m_3200:
    02607       tbits[0] = 0x80 | ((unsigned char)((valid_bytes >> 24) & 0x1f));
    02608       tbits[1] = (unsigned char)((valid_bytes >> 16) & 0xff);
    02609       tbits[2] = (unsigned char)((valid_bytes >> 8) & 0xff);
    02610       tbits[3] = (unsigned char)(valid_bytes & 0xff);
    02611       break;
    02612
    02613     case m_lex7500:
    02614       break;
    02615     }
    02616
    02617
    02618     if (anyDots) {
    02619       anyCol = 1;
    02620     } else {
    02621       /* there are no dots, make empy package */
    02622 #ifdef DEBUG
    02623       /*     stp_erprintf("-- empty col %i\n", x); */
    02624 #endif
    02625     }
    02626   }
    02627
    02628 #ifdef DEBUG
    02629   stp_erprintf("lexmark: 4\n");
    02630 #endif
    02631
    02632   clen=((unsigned char *)p)-prnBuf;
    02633
    02634   switch(caps->model)    {
    02635     case m_z52:
    02636     case m_z42:
    02637   prnBuf[IDX_SEQLEN]  =(unsigned char)(clen >> 24);
    02638   prnBuf[IDX_SEQLEN+1]  =(unsigned char)(clen >> 16);
    02639   prnBuf[IDX_SEQLEN+2]  =(unsigned char)(clen >> 8);
    02640   prnBuf[IDX_SEQLEN+3]=(unsigned char)(clen & 0xFF);
    02641   break;
    02642
    02643   case m_3200:
    02644     prnBuf[18] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 16);
    02645     prnBuf[19] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 8);
    02646     prnBuf[20] = (unsigned char)((clen - LXM_3200_HEADERSIZE) & 0xff);
    02647     prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
    02648     break;
    02649
    02650   default:
    02651     break;
    02652   }
    02653
    02654   if (anyCol) {
    02655     /* fist, move the paper */
    02656     paper_shift(v, (*paperShift), caps);
    02657     *paperShift=0;
    02658
    02659     /* now we write the image line */
    02660     stp_zfwrite((const char *)prnBuf,1,clen,v);
    02661 #ifdef DEBUG
    02662     lex_write_tmp_file(dbgfileprn, (void *)prnBuf,clen);
    02663     stp_erprintf("lexmark: line written.\n");
    02664 #endif
    02665     return 1;
    02666   } else {
    02667 #ifdef DEBUG
    02668     stp_erprintf("-- empty line\n");
    02669 #endif
    02670     return 0;
    02671   }
    02672
    02673   /* Send a line of raster graphics... */
    02674
    02675   return 0;
    02676 }
    02677
    02678
    02679
    02680 #ifdef DEBUG
    02681 const stp_vars_t *lex_open_tmp_file() {
    02682   int i;
    02683   const stp_vars_t *ofile;
    02684   char tmpstr[256];
    02685
    02686       stp_erprintf(" create file !\n");
    02687   for (i=0, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r");
    02688        ofile != NULL;
    02689        i++, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r")) {
    02690     if (ofile != NULL)
    02691       {
    02692         fclose(ofile);
    02693       }
    02694   }
    02695       stp_erprintf("Create file %s !\n", tmpstr);
    02696   ofile = fopen(tmpstr, "wb");
    02697   if (ofile == NULL)
    02698     {
    02699       stp_erprintf("Can't create file !\n");
    02700       stp_abort();
    02701     }
    02702   return ofile;
    02703 }
    02704
    02705 void lex_tmp_file_deinit(const stp_vars_t *file) {
    02706   stp_erprintf("Close file %lx\n", file);
    02707   fclose(file);
    02708 }
    02709
    02710 const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length) {
    02711   fwrite(data, 1, length, ofile);
    02712 }
    02713
    02714
    02715 #endif
    02716
    02717
    02718 static void
    02719 flush_pass(stp_vars_t *v, int passno, int vertical_subpass)
    02720 {
    02721   stp_lineoff_t        *lineoffs   = stp_get_lineoffsets_by_pass(v, passno);
    02722   stp_lineactive_t     *lineactive = stp_get_lineactive_by_pass(v, passno);
    02723   const stp_linebufs_t *bufs       = stp_get_linebases_by_pass(v, passno);
    02724   stp_pass_t           *pass       = stp_get_pass_by_pass(v, passno);
    02725   stp_linecount_t      *linecount  = stp_get_linecount_by_pass(v, passno);
    02726   lexm_privdata_weave *pd =
    02727     (lexm_privdata_weave *) stp_get_component_data(v, "Driver");
    02728   int width = pd->width;
    02729   int hoffset = pd->hoffset;
    02730   int model = pd->model;
    02731   int xdpi = pd->xdpi;
    02732   int ydpi = pd->ydpi;
    02733   int physical_xdpi = pd->physical_xdpi;
    02734   int lwidth = (width + (pd->horizontal_weave - 1)) / pd->horizontal_weave;
    02735   int microoffset = vertical_subpass & (pd->horizontal_weave - 1);
    02736
    02737   int prn_mode;
    02738   int j; /* color counter */
    02739   const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
    02740   int paperShift;
    02741   Lexmark_head_colors head_colors[3]={{0, NULL,     0,  64/2, 64},
    02742                                       {0, NULL,  64/2, 128/2, 64},
    02743                                       {0, NULL, 128/2, 192/2, 64}};
    02744
    02745
    02746 #ifdef DEBUG
    02747   stp_erprintf("Lexmark: flush_pass, here we are !\n");
    02748   stp_erprintf("  passno %i, pd->ncolors %i, width %d, lwidth %d, linecount k % d, linecount m % d, bitwidth %d\n",
    02749                passno, pd->ncolors, width, lwidth, /*linecount[0].p.k, linecount[0].p.m,*/ pd->bitwidth);
    02750   stp_erprintf("microoffset %d, vertical_subpass %d, pd->horizontal_weave %d\n", microoffset,vertical_subpass, pd->horizontal_weave);
    02751
    02752   stp_erprintf("Lexmark: last_pass_offset %d, logicalpassstart %d\n", pd->last_pass_offset, pass->logicalpassstart);
    02753   stp_erprintf("Lexmark: vertical adapt: caps->y_raster_res %d, ydpi %d,  \n", caps->y_raster_res, ydpi);
    02754
    02755 #endif
    02756
    02757   if (1) { /* wisi */
    02758
    02759 #ifdef DEBUG
    02760   stp_erprintf("1\n");
    02761   stp_erprintf("\n");
    02762   stp_erprintf("lineoffs[0].v[j]  %d\n", lineoffs[0].v[0]);
    02763   stp_erprintf("lineoffs[0].v[j]  %d\n", lineoffs[0].v[1]);
    02764
    02765 #endif
    02766
    02767   switch (physical_xdpi) {
    02768   case 300:
    02769     prn_mode = PRINT_MODE_300;
    02770     break;
    02771   case 600:
    02772     prn_mode = PRINT_MODE_600;
    02773     break;
    02774   case 1200:
    02775     prn_mode = PRINT_MODE_1200;
    02776     break;
    02777   default:
    02778 #ifdef DEBUG
    02779     stp_erprintf("Eror: Unsupported phys resolution (%d)\n", physical_xdpi);
    02780 #endif
    02781     return;
    02782     break;
    02783   }
    02784   /* calculate paper shift and adapt actual resoution to physical positioning resolution */
    02785   paperShift = (pass->logicalpassstart - pd->last_pass_offset) * (caps->y_raster_res/ydpi);
    02786
    02787
    02788       /*** do we have to print something with the color cartridge ? ***/
    02789       if ((STP_ECOLOR_C < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_C] > 0))
    02790         {
    02791           head_colors[0].line = bufs[0].v[STP_ECOLOR_C];
    02792           head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_C];
    02793         }
    02794       else
    02795         {
    02796           head_colors[0].line = NULL;
    02797           head_colors[0].used_jets = 0;
    02798         }
    02799
    02800       if ((STP_ECOLOR_M < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_M] > 0))
    02801         {
    02802           head_colors[1].line = bufs[0].v[STP_ECOLOR_M];
    02803           head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_M];
    02804         }
    02805       else
    02806         {
    02807           head_colors[1].line = 0;
    02808           head_colors[1].used_jets = 0;
    02809         }
    02810
    02811       if ((STP_ECOLOR_Y < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_Y] > 0))
    02812         {
    02813           head_colors[2].line = bufs[0].v[STP_ECOLOR_Y];
    02814           head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_Y];
    02815         }
    02816       else
    02817         {
    02818           head_colors[2].line = 0;
    02819           head_colors[2].used_jets = 0;
    02820         }
    02821
    02822       if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
    02823
    02824
    02825
    02826 #ifdef DEBUG
    02827         stp_erprintf("lexmark_write: lwidth %d\n", lwidth);
    02828 #endif
    02829         lexmark_write(v,                /* I - Print file or command */
    02830                       pd->outbuf,/*unsigned char *prnBuf,   mem block to buffer output */
    02831                       &paperShift,           /* int *paperShift, */
    02832                       pd->direction,                     /* int direction, */
    02833                       pd->jets,       /* num of inks to print */
    02834                       caps,                  /* const lexmark_cap_t *   caps,       I - Printer model */
    02835                       pd->ink_parameter,
    02836                       xdpi,                  /* int xresolution, */
    02837                       2,                     /* yCount,*/
    02838                       head_colors,           /* Lexmark_head_colors *head_colors, */
    02839                       (lwidth+7)/8, /* length,   I - Length of bitmap data of one line in bytes */
    02840                       prn_mode | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_M,       /* mode,      I - Which color */
    02841                       ydpi,                  /* ydpi,    I - Vertical resolution */
    02842                       lwidth,      /* width,     I - Printed width in pixles*/
    02843                       hoffset+microoffset,   /* offset  I - Offset from left side in x_raster_res DPI */
    02844                       0                      /* dmt */);
    02845         if (pd->bidirectional)
    02846           pd->direction = (pd->direction +1) & 1;
    02847       }
    02848
    02849
    02850       /*** do we have to print somthing with black or photo cartridge ? ***/
    02851       /* we print with the photo or black cartidge */
    02852
    02853     if (pd->jets != 208)
    02854       {
    02855         /* we have photo or black cartridge */
    02856         if ((STP_ECOLOR_LC < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LC] > 0))
    02857           {
    02858             head_colors[0].line = bufs[0].v[STP_ECOLOR_LC];
    02859             head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_LC];
    02860           }
    02861         else
    02862           {
    02863             head_colors[0].line = 0;
    02864             head_colors[0].used_jets = 0;
    02865           }
    02866
    02867             if ((STP_ECOLOR_LM < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LM] > 0))
    02868           {
    02869             head_colors[1].line = bufs[0].v[STP_ECOLOR_LM];
    02870             head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_LM];
    02871           }
    02872         else
    02873           {
    02874             head_colors[1].line = 0;
    02875             head_colors[1].used_jets = 0;
    02876           }
    02877
    02878             if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
    02879           {
    02880             head_colors[2].line = bufs[0].v[STP_ECOLOR_K];
    02881             head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_K];
    02882           }
    02883         else
    02884           {
    02885             head_colors[2].line = 0;
    02886             head_colors[2].used_jets = 0;
    02887           }
    02888       }
    02889     else
    02890       {
    02891         if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
    02892           {
    02893             /* we have black cartridge; we have to print with all 208 jets at once */
    02894             head_colors[0].line = bufs[0].v[STP_ECOLOR_K];
    02895             head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_K];
    02896             head_colors[0].head_nozzle_start = 0;
    02897             head_colors[0].head_nozzle_end = pd->jets/2;
    02898             head_colors[2].line = NULL;
    02899             head_colors[2].used_jets = 0;
    02900             head_colors[2].head_nozzle_start = 0;
    02901             head_colors[2].head_nozzle_end = 0;
    02902             head_colors[1].line = NULL;
    02903             head_colors[1].used_jets = 0;
    02904             head_colors[1].head_nozzle_start = 0;
    02905             head_colors[1].head_nozzle_end = 0;
    02906           }
    02907         else
    02908           {
    02909             head_colors[2].line = NULL;
    02910             head_colors[2].used_jets = 0;
    02911             head_colors[2].head_nozzle_start = 0;
    02912             head_colors[2].head_nozzle_end = 0;
    02913             head_colors[1].line = NULL;
    02914             head_colors[1].used_jets = 0;
    02915             head_colors[1].head_nozzle_start = 0;
    02916             head_colors[1].head_nozzle_end = 0;
    02917             head_colors[0].line = NULL;
    02918             head_colors[0].used_jets = 0;
    02919             head_colors[0].head_nozzle_start = 0;
    02920             head_colors[0].head_nozzle_end = 0;
    02921           }
    02922       }
    02923
    02924      if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
    02925
    02926     lexmark_write(v,            /* I - Print file or command */
    02927                   pd->outbuf,/*unsigned char *prnBuf,   mem block to buffer output */
    02928                   &paperShift,           /* int *paperShift, */
    02929                   pd->direction,             /* int direction, */
    02930                   pd->jets,              /* num of inks to print */
    02931                   caps,                  /* const lexmark_cap_t *   caps,     I - Printer model */
    02932                   pd->ink_parameter,
    02933                   xdpi,                  /* int xresolution, */
    02934                   2,                     /* yCount,*/
    02935                   head_colors,           /* Lexmark_head_colors *head_colors, */
    02936                   (lwidth+7)/8, /* length,       I - Length of bitmap data of one line in bytes */
    02937                   prn_mode | COLOR_MODE_LC | COLOR_MODE_LM | COLOR_MODE_K,       /* mode,        I - Which color */
    02938                   ydpi,                  /* ydpi,        I - Vertical resolution */
    02939                   lwidth,      /* width,         I - Printed width in pixles*/
    02940                   hoffset+microoffset,   /* offset  I - Offset from left side in x_raster_res DPI */
    02941                   0                      /* dmt */);
    02942     if (pd->bidirectional)
    02943       {
    02944         pd->direction = (pd->direction +1) & 1;
    02945       }
    02946     }
    02947   /* store paper position in respect if there was a paper shift */
    02948   pd->last_pass_offset = pass->logicalpassstart - (paperShift / (caps->y_raster_res/ydpi));
    02949   }
    02950
    02951   for (j = 0; j < pd->ncolors; j++)
    02952     {
    02953       lineoffs[0].v[j]  = 0;
    02954       linecount[0].v[j] = 0;
    02955     }
    02956
    02957 #ifdef DEBUG
    02958   stp_erprintf("lexmark_write finished\n");
    02959 #endif
    02960
    02961 }
    02962
    02963
    02964
    02965
    02966
    02967 #ifdef DEBUG
    02968
    02969 static void testprint(testdata *td)
    02970 {
    02971   int icol, i;
    02972   char dummy1[256], dummy2[256];
    02973   lexmark_linebufs_t linebufs;
    02974
    02975   /* init */
    02976   for (i=0; i < (sizeof(linebufs.v)/sizeof(linebufs.v[0])); i++) {
    02977     linebufs.v[i] = NULL;
    02978   }
    02979
    02980   /*let's go */
    02981   td->ifile = fopen("/t1.ppm", "rb");
    02982   if (td->ifile != NULL) {
    02983     /* find "{" */
    02984     fscanf(td->ifile, "%[^{]{%[^\"]\"%d %d %d %d\",", dummy1, dummy2, &(td->x), &(td->y), &(td->cols), &(td->deep));
    02985     td->cols -= 1; /* we reduce it by one because fist color will be ignored */
    02986     td->input_line = (char *)stp_malloc(td->x+10);
    02987     stp_erprintf("<%s> <%s>\n", dummy1, dummy2);
    02988     stp_erprintf("%d %d %d %d\n", td->x, td->y, td->cols, td->deep);
    02989     if (td->cols > 16) {
    02990       stp_erprintf("too many colors !!\n");
    02991       return;
    02992     }
    02993
    02994     /* read the colors */
    02995     fscanf(td->ifile, "%[^\"]\"%c       c %[^\"]\",", dummy1, dummy2, dummy2); /* jump over first color */
    02996     for (icol=0; icol < td->cols; icol++) {  /* we ignor the first color. It is "no dot". */
    02997       fscanf(td->ifile, "%[^\"]\"%c     c %[^\"]\",", dummy1, &(td->colchar[icol]), dummy2);
    02998       stp_erprintf("colchar %d <%c>\n", i, td->colchar[icol]);
    02999     }
    03000
    03001
    03002     if (td->cols > 5) {
    03003       td->cols = 7;
    03004       for (icol=0; icol < td->cols; icol++) {  /* we ignor the first color. It is "no dot". */
    03005         linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
    03006       }
    03007     } else if (td->cols > 4) {
    03008       td->cols = 5;
    03009       for (icol=0; icol < td->cols; icol++) {  /* we ignor the first color. It is "no dot". */
    03010         linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
    03011       }
    03012     } else {
    03013       td->cols = 1;
    03014       linebufs.v[0] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
    03015     }
    03016   } else {
    03017     stp_erprintf("can't open file !\n");
    03018   }
    03019 }
    03020
    03021
    03022 static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs)
    03023 {
    03024   char dummy1[256];
    03025   int icol, ix;
    03026
    03027   stp_erprintf("start readtestprintline\n");
    03028   for (icol=0; icol < 7; icol++) {
    03029     if (linebufs->v[icol] != NULL) {
    03030       memset(linebufs->v[icol], 0, (td->x+7)/8);  /* clean line */
    03031     }
    03032   }
    03033   stp_erprintf("1 readtestprintline cols %d\n", td->cols);
    03034
    03035
    03036   fscanf(td->ifile, "%[^\"]\"%[^\"]\",", dummy1, td->input_line);
    03037   for (icol=0; icol < td->cols; icol++) {
    03038    for (ix=0; ix < td->x; ix++) {
    03039       if (td->input_line[ix] == td->colchar[icol]) {
    03040         /* set the dot */
    03041         if (icol != 0) {
    03042           linebufs->v[icol-1][ix/8] |= 1 << (ix%8);
    03043         } else {
    03044           /* this is specific, we set ymc */
    03045           linebufs->p.y[ix/8] |= 1 << (ix%8);
    03046           linebufs->p.m[ix/8] |= 1 << (ix%8);
    03047           linebufs->p.c[ix/8] |= 1 << (ix%8);
    03048         }
    03049       }
    03050     }
    03051   }
    03052   /* stp_erprintf("pixchar  <%s><%s>\n",dummy1, td->input_line);*/
    03053 }
    03054
    03055 #endif
    03056
    03057
    03058 static stp_family_t print_lexmark_module_data =
    03059   {
    03060     &print_lexmark_printfuncs,
    03061     NULL
    03062   };
    03063
    03064 static int
    03065 print_lexmark_module_init(void)
    03066 {
    03067   return stp_family_register(print_lexmark_module_data.printer_list);
    03068 }
    03069
    03070
    03071 static int
    03072 print_lexmark_module_exit(void)
    03073 {
    03074   return stp_family_unregister(print_lexmark_module_data.printer_list);
    03075 }
    03076
    03077
    03078 /* Module header */
    03079 #define stp_module_version print_lexmark_LTX_stp_module_version
    03080 #define stp_module_data print_lexmark_LTX_stp_module_data
    03081
    03082 stp_module_version_t stp_module_version = {0, 0};
    03083
    03084 stp_module_t stp_module_data =
    03085   {
    03086     "lexmark",
    03087     VERSION,
    03088     "Lexmark family driver",
    03089     STP_MODULE_CLASS_FAMILY,
    03090     NULL,
    03091     print_lexmark_module_init,
    03092     print_lexmark_module_exit,
    03093     (void *) &print_lexmark_module_data
    03094   };
    03095