1 
2 /*
3  *
4  *   Print plug-in Lexmark driver for the GIMP.
5  *
6  *   Copyright 2000 Richard Wisenoecker (richard.wisenoecker@gmx.at) and
7  *      Alwin Stolk (p.a.stolk@tmx.nl)
8  *
9  *   The plug-in is based on the code of the CANON BJL plugin for the GIMP
10  *   of Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu).
11  *
12  *
13  *   This program is free software; you can redistribute it and/or modify it
14  *   under the terms of the GNU General Public License as published by the Free
15  *   Software Foundation; either version 2 of the License, or (at your option)
16  *   any later version.
17  *
18  *   This program is distributed in the hope that it will be useful, but
19  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21  *   for more details.
22  *
23  *   You should have received a copy of the GNU General Public License
24  *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
25  */
26 
27 /*
28  * This file must include only standard C header files.  The core code must
29  * compile on generic platforms that don't support glib, gimp, gtk, etc.
30  */
31 
32 /*
33  * !!! IMPORTANT !!!  Some short information: Border and page offsets
34  * are defined in 1/72 DPI. This mean, that the parameter defined at
35  * lexmark_cap_t which defines positions are in 1/72 DPI. At
36  * lexmark_print the unit will be changed dependent on the printer,
37  * according to the value defined at lexmark_cap_t.x_raster_res and
38  * lexmark_cap_t.y_raster_res. These two parameters are specifying the
39  * resolution used for positioning the printer head (it is not the
40  * resolution used for printing!).
41  */
42 
43 /* TODO-LIST
44  *
45  *   * implement the left border
46  *
47  */
48 
49 /*#define DEBUG 1*/
50 #define USEEPSEWAVE 1
51 
52 #ifdef __GNUC__
53 #define inline __inline__
54 #endif
55 
56 #ifdef HAVE_CONFIG_H
57 #include <config.h>
58 #endif
59 #include <gutenprint/gutenprint.h>
60 #include <gutenprint/gutenprint-intl-internal.h>
61 #include "gutenprint-internal.h"
62 #include <string.h>
63 #ifdef DEBUG
64 #include <stdio.h>
65 #endif
66 
67 #define STP_ECOLOR_LC 4
68 #define STP_ECOLOR_LM 5
69 #define STP_ECOLOR_LY 6
70 
71 #define false 0
72 #define true  1
73 
74 #define max(a, b) ((a > b) ? (a) : (b))
75 #define INCH(x)		(72 * x)
76 
77 static const stp_dotsize_t single_dotsize[] =
78 {
79   { 0x1, 1.0 }
80 };
81 
82 static const stp_shade_t photo_dither_shades[] =
83 {
84   { 1.0000, 1, single_dotsize },
85   { 0.3333, 1, single_dotsize },
86 };
87 
88 
89 typedef enum Lex_model { m_lex7500,   m_z52=10052, m_z42=10042, m_3200=3200 } Lex_model;
90 
91 #define NCHANNELS (7)
92 
93 typedef union {			/* Offsets from the start of each line */
94   unsigned long v[NCHANNELS];		/* (really pass) */
95   struct {     /* IMPORTANT: order corresponds to STP_ECOLOR_* */
96     unsigned long k;
97     unsigned long c;
98     unsigned long m;
99     unsigned long y;
100     unsigned long C;
101     unsigned long M;
102     unsigned long Y;
103   } p;
104 } lexmark_lineoff_t;
105 
106 typedef union {			/* Base pointers for each pass */
107   unsigned char *v[NCHANNELS];
108   struct {     /* IMPORTANT: order corresponds to STP_ECOLOR_* */
109     unsigned char *k;
110     unsigned char *c;
111     unsigned char *m;
112     unsigned char *y;
113     unsigned char *C;
114     unsigned char *M;
115     unsigned char *Y;
116   } p;
117 } lexmark_linebufs_t;
118 
119 
120 
121 #ifdef DEBUG
122 typedef struct testdata {
123   FILE *ifile;
124   int x, y, cols, deep;
125   char colchar[16];
126   char *input_line;
127 } testdata;
128 
129 const stp_vars_t **dbgfileprn;
130 int  lex_show_lcount, lex_show_length;
131 
132 const stp_vars_t *lex_open_tmp_file();
133 const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length);
134 static void testprint(testdata *td);
135 static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs);
136 #endif
137 
138 static void
139 flush_pass(stp_vars_t *v, int passno, int vertical_subpass);
140 
141 /*** resolution specific parameters */
142 #define DPI300   0
143 #define DPI600   1
144 #define DPI1200  2
145 #define DPI2400  3
146 #define DPItest  4
147 
148 #define V_NOZZLE_MASK 0x3
149 #define H_NOZZLE_MASK 0xc
150 #define NOZZLE_MASK   0xf
151 
152 #define PRINT_MODE_300   0x100
153 #define PRINT_MODE_600   0x200
154 #define PRINT_MODE_1200  0x300
155 #define PRINT_MODE_2400  0x400
156 
157 #define COLOR_MODE_K      0x1000
158 #define COLOR_MODE_C      0x2000
159 #define COLOR_MODE_Y      0x4000
160 #define COLOR_MODE_M      0x8000
161 #define COLOR_MODE_LC    0x10000
162 #define COLOR_MODE_LY    0x20000
163 #define COLOR_MODE_LM    0x40000
164 #define COLOR_MODE_CMYK   (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y | COLOR_MODE_K)
165 #define COLOR_MODE_CMY    (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y)
166 #define COLOR_MODE_CcMcYK (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y | COLOR_MODE_K)
167 #define COLOR_MODE_CcMcY  (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y)
168 
169 #define COLOR_MODE_MASK  0x7f000
170 #define PRINT_MODE_MASK    0xf00
171 #define COLOR_MODE_PHOTO (COLOR_MODE_LC | COLOR_MODE_LM)
172 
173 #define BWR      0
174 #define BWL      1
175 #define CR       2
176 #define CL       3
177 
178 
179 static const char standard_sat_adjustment[] =
180 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
181 "<gutenprint>\n"
182 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
183 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
184 /* C */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* B */
185 /* B */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* M */
186 /* M */  "1.00 0.95 0.90 0.90 0.90 0.90 0.90 0.90 "  /* R */
187 /* R */  "0.90 0.95 0.95 1.00 1.00 1.00 1.00 1.00 "  /* Y */
188 /* Y */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* G */
189 /* G */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* C */
190 "</sequence>\n"
191 "</curve>\n"
192 "</gutenprint>\n";
193 
194 static const char standard_lum_adjustment[] =
195 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
196 "<gutenprint>\n"
197 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
198 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
199 /* C */  "0.65 0.67 0.70 0.72 0.77 0.80 0.82 0.85 "  /* B */
200 /* B */  "0.87 0.86 0.82 0.79 0.79 0.82 0.85 0.88 "  /* M */
201 /* M */  "0.92 0.95 0.96 0.97 0.97 0.97 0.96 0.96 "  /* R */
202 /* R */  "0.96 0.97 0.97 0.98 0.99 1.00 1.00 1.00 "  /* Y */
203 /* Y */  "1.00 0.97 0.95 0.94 0.93 0.92 0.90 0.86 "  /* G */
204 /* G */  "0.79 0.76 0.71 0.68 0.68 0.68 0.68 0.66 "  /* C */
205 "</sequence>\n"
206 "</curve>\n"
207 "</gutenprint>\n";
208 
209 static const char standard_hue_adjustment[] =
210 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
211 "<gutenprint>\n"
212 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
213 "<sequence count=\"48\" lower-bound=\"-6\" upper-bound=\"6\">\n"
214 /* C */  "0.00 0.06 0.10 0.10 0.06 -.01 -.09 -.17 "  /* B */
215 /* B */  "-.25 -.33 -.38 -.38 -.36 -.34 -.34 -.34 "  /* M */
216 /* M */  "-.34 -.34 -.36 -.40 -.50 -.40 -.30 -.20 "  /* R */
217 /* R */  "-.12 -.07 -.04 -.02 0.00 0.00 0.00 0.00 "  /* Y */
218 /* Y */  "0.00 0.00 0.00 -.05 -.10 -.15 -.22 -.24 "  /* G */
219 /* G */  "-.26 -.30 -.33 -.28 -.25 -.20 -.13 -.06 "  /* C */
220 "</sequence>\n"
221 "</curve>\n"
222 "</gutenprint>\n";
223 
224 
225 /* Codes for possible ink-tank combinations.
226  * Each combo is represented by the colors that can be used with
227  * the installed ink-tank(s)
228  * Combinations of the codes represent the combinations allowed for a model
229  */
230 #define LEXMARK_INK_K           1
231 #define LEXMARK_INK_CMY         2
232 #define LEXMARK_INK_CMYK        4
233 #define LEXMARK_INK_CcMmYK      8
234 #define LEXMARK_INK_CcMmYy     16
235 #define LEXMARK_INK_CcMmYyK    32
236 
237 #define LEXMARK_INK_BLACK_MASK (LEXMARK_INK_K|LEXMARK_INK_CMYK|\
238                               LEXMARK_INK_CcMmYK|LEXMARK_INK_CcMmYyK)
239 
240 #define LEXMARK_INK_PHOTO_MASK (LEXMARK_INK_CcMmYy|LEXMARK_INK_CcMmYK|\
241                               LEXMARK_INK_CcMmYyK)
242 
243 /* document feeding */
244 #define LEXMARK_SLOT_ASF1    1
245 #define LEXMARK_SLOT_ASF2    2
246 #define LEXMARK_SLOT_MAN1    4
247 #define LEXMARK_SLOT_MAN2    8
248 
249 /* model peculiarities */
250 #define LEXMARK_CAP_DMT       1<<0    /* Drop Modulation Technology */
251 #define LEXMARK_CAP_MSB_FIRST 1<<1    /* how to send data           */
252 #define LEXMARK_CAP_CMD61     1<<2    /* uses command #0x61         */
253 #define LEXMARK_CAP_CMD6d     1<<3    /* uses command #0x6d         */
254 #define LEXMARK_CAP_CMD70     1<<4    /* uses command #0x70         */
255 #define LEXMARK_CAP_CMD72     1<<5    /* uses command #0x72         */
256 
257 
258 static const int lr_shift_color[10] = { 9, 18, 2*18 }; /* vertical distance between ever 2nd  inkjet (related to resolution) */
259 static const int lr_shift_black[10] = { 9, 18, 2*18 }; /* vertical distance between ever 2nd  inkjet (related to resolution) */
260 
261 static const stp_parameter_t the_parameters[] =
262 {
263   {
264     "PageSize", N_("Page Size"), "Color=No,Category=Basic Printer Setup",
265     N_("Size of the paper being printed to"),
266     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
267     STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
268   },
269   {
270     "MediaType", N_("Media Type"), "Color=Yes,Category=Basic Printer Setup",
271     N_("Type of media (plain paper, photo paper, etc.)"),
272     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
273     STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
274   },
275   {
276     "InputSlot", N_("Media Source"), "Color=No,Category=Basic Printer Setup",
277     N_("Source (input slot) of the media"),
278     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
279     STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
280   },
281   {
282     "Resolution", N_("Resolution"), "Color=Yes,Category=Basic Printer Setup",
283     N_("Resolution and quality of the print"),
284     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
285     STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
286   },
287   {
288     "InkType", N_("Ink Type"), "Color=Yes,Category=Advanced Printer Setup",
289     N_("Type of ink in the printer"),
290     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
291     STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
292   },
293   {
294     "InkChannels", N_("Ink Channels"), "Color=Yes,Category=Advanced Printer Functionality",
295     N_("Ink Channels"),
296     STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE,
297     STP_PARAMETER_LEVEL_INTERNAL, 0, 0, STP_CHANNEL_NONE, 0, 0
298   },
299   {
300     "PrintingMode", N_("Printing Mode"), "Color=Yes,Category=Core Parameter",
301     N_("Printing Output Mode"),
302     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
303     STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
304   },
305 };
306 
307 static const int the_parameter_count =
308 sizeof(the_parameters) / sizeof(const stp_parameter_t);
309 
310 typedef struct
311 {
312   const stp_parameter_t param;
313   double min;
314   double max;
315   double defval;
316   int color_only;
317 } float_param_t;
318 
319 static const float_param_t float_parameters[] =
320 {
321   {
322     {
323       "CyanDensity", N_("Cyan Density"), "Color=Yes,Category=Output Level Adjustment",
324       N_("Adjust the cyan density"),
325       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
326       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 1, 1, 0
327     }, 0.0, 2.0, 1.0, 1
328   },
329   {
330     {
331       "MagentaDensity", N_("Magenta Density"), "Color=Yes,Category=Output Level Adjustment",
332       N_("Adjust the magenta density"),
333       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
334       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 2, 1, 0
335     }, 0.0, 2.0, 1.0, 1
336   },
337   {
338     {
339       "YellowDensity", N_("Yellow Density"), "Color=Yes,Category=Output Level Adjustment",
340       N_("Adjust the yellow density"),
341       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
342       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 3, 1, 0
343     }, 0.0, 2.0, 1.0, 1
344   },
345   {
346     {
347       "BlackDensity", N_("Black Density"), "Color=Yes,Category=Output Level Adjustment",
348       N_("Adjust the black density"),
349       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
350       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 0, 1, 0
351     }, 0.0, 2.0, 1.0, 1
352   },
353   {
354     {
355       "LightCyanTrans", N_("Light Cyan Transition"), "Color=Yes,Category=Advanced Ink Adjustment",
356       N_("Light Cyan Transition"),
357       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
358       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, STP_CHANNEL_NONE, 1, 0
359     }, 0.0, 5.0, 1.0, 1
360   },
361   {
362     {
363       "LightMagentaTrans", N_("Light Magenta Transition"), "Color=Yes,Category=Advanced Ink Adjustment",
364       N_("Light Magenta Transition"),
365       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
366       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, STP_CHANNEL_NONE, 1, 0
367     }, 0.0, 5.0, 1.0, 1
368   },
369 };
370 
371 static const int float_parameter_count =
372 sizeof(float_parameters) / sizeof(const float_param_t);
373 
374 /* returns the offset of the first jet when printing in the other direction */
get_lr_shift(int mode)375 static int get_lr_shift(int mode)
376 {
377 
378   const int *ptr_lr_shift;
379 
380       /* K could only be present if black is printed only. */
381   if((mode & COLOR_MODE_K) == (mode & COLOR_MODE_MASK)) {
382     ptr_lr_shift = lr_shift_black;
383   } else {
384     ptr_lr_shift = lr_shift_color;
385   }
386 
387       switch(mode & PRINT_MODE_MASK) 	{
388 	case PRINT_MODE_300:
389 	  return ptr_lr_shift[0];
390 	  break;
391 	case PRINT_MODE_600:
392 	  return ptr_lr_shift[1];
393 	  break;
394 	case PRINT_MODE_1200:
395 	  return ptr_lr_shift[2];
396 	  break;
397 	case PRINT_MODE_2400:
398 	  return ptr_lr_shift[2];
399 	  break;
400       }
401       return 0;
402 }
403 
404 
405 /*
406  * head offsets for z52:
407  *
408  *      black       black          color         photo
409  *    cartridge   cartridge      cartridge     cartridge
410  *      mode I     mode II
411  *
412  *              v                 +-----+ --    +-----+ ---
413  * --- +-----+ ---             v  |     | ^     |     |  ^
414  *  ^  |     | --- +-----+ --- -- |  C  | 64    | LC  |  |
415  *  |  |     |  ^  |     |  ^  40 |     | v  v  |     |  |
416  *  |  |     |     |     |  |  -- +-----+ -- -- +-----+  |
417  *  |  |     |     |     |  |  ^             28          |
418  *  |  |     |     |     |  |     +-----+ -- -- +-----+  |
419  *     |     |     |     |  |     |     | ^  ^  |     |  |
420  * 208 |  K  |     |  K  | 192    |  M  | 64    | LM  | 240
421  *     |     |     |     |  |     |     | v  v  |     |  |
422  *  |  |     |     |     |  |     +-----+ -- -- +-----+  |
423  *  |  |     |     |     |  |  v             28          |
424  *  |  |     |     |     |  |  -- +-----+ -- -- +-----+  |
425  *  |  |     |     |     |  v  40 |     | ^  ^  |     |  |
426  *  v  |     |     +-----+ --- -- |  Y  | 64    |  K  |  |
427  * --- +-----+                 ^  |     | v     |     |  v
428  *                                +-----+ --    +-----+ ---
429  *
430  */
431 
432 static const int head_offset_cmyk[] =
433 {70, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
434 /* 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 */
435 static const int head_offset_cmy[] =
436 {0, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
437 static const int head_offset_cCmMyk[] =
438 {0, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
439 
440 
441 
442 
443 /**************************************************************************/
444 /**** Data structures which are describing printer specific parameters ****/
445 
446 /* resolution specific parameters (substructure of lexmark_cap_t) */
447 typedef struct {
448   const char *name;
449   const char *text;
450   int hres;
451   int vres;
452   int softweave;
453   int vertical_passes;
454   int vertical_oversample;
455   int unidirectional;      /* print bi/unidirectional */
456   int resid;               /* resolution id */
457 } lexmark_res_t;
458 
459 #define LEXM_RES_COUNT 30
460 typedef lexmark_res_t lexmark_res_t_array[LEXM_RES_COUNT];
461 
462 
463 /* ink type parameters (substructure of lexmark_cap_t) */
464 typedef struct {
465   int ncolors;
466   unsigned int used_colors; /* specifies the head colors to be used (e.g. COLOR_MODE_K */
467   unsigned int pass_length; /* available jets for one color */
468   int v_top_head_offset;    /* offset from top, where the first jet will be found */
469   int h_catridge_offset;    /* horizontal offset of cartridges */
470   int h_direction_offset;   /* Offset when printing in the other direction */
471   const int *head_offset;   /* specifies the offset of head colors */
472 } lexmark_inkparam_t;
473 
474 typedef struct
475 {
476   const char *name;
477   const char *text;
478   lexmark_inkparam_t ink_parameter[2];
479 } lexmark_inkname_t;
480 
481 
482 /* main structure which describes all printer specific parameters */
483 typedef struct {
484   Lex_model model;    /* printer model */
485   int max_paper_width;  /* maximum printable paper size in 1/72 inch */
486   int max_paper_height;
487   int min_paper_width;  /* Maximum paper width, in points */
488   int min_paper_height; /* Maximum paper height, in points */
489   int max_xdpi;
490   int max_ydpi;
491   int max_quality;
492   int border_left;    /* unit is 72 DPI */
493   int border_right;
494   int border_top;
495   int border_bottom;
496   int inks;           /* installable cartridges (LEXMARK_INK_*) */
497   int slots;          /* available paperslots */
498   int features;       /* special bjl settings */
499   /*** printer internal parameters ***/
500   /* the unit of the following parameters is identical with max phys unit of the printer */
501   int offset_left_border;      /* Offset to the left paper border (== border_left=0) */
502   int offset_top_border;       /* Offset to the top paper border (== border_top=0) */
503   int x_raster_res;            /* horizontal resolution for positioning of the printer head in DPI */
504   int y_raster_res;            /* vertical   resolution for positioning of the printer head in DPI */
505   const lexmark_res_t_array *res_parameters; /* resolution specific parameters; last entry has resid = -1 */
506   const lexmark_inkname_t *ink_types;  /* type of supported inks */
507   const char *lum_adjustment;
508   const char *hue_adjustment;
509   const char *sat_adjustment;
510 } lexmark_cap_t;
511 
512 
513 /*****************************************************************/
514 /**** initialize printer specific data structures ****/
515 
516 /*
517  * z52 specific parameters
518  */
519 #define LX_Z52_300_DPI  1
520 #define LX_Z52_600_DPI  3
521 #define LX_Z52_1200_DPI 4
522 #define LX_Z52_2400_DPI 5
523 
524 #define LX_Z52_COLOR_PRINT 0
525 #define LX_Z52_BLACK_PRINT 1
526 
527 #define LX_PSHIFT                   0x13
528 #define LX_Z52_COLOR_MODE_POS       0x9
529 #define LX_Z52_RESOLUTION_POS       0x7
530 #define LX_Z52_PRINT_DIRECTION_POS  0x8
531 
532 /*static const int IDX_Z52ID =2;*/
533 static const int IDX_SEQLEN=3;
534 
535 /*
536    head:
537      1 .. black,
538      0 .. color
539 
540    resolution:
541      1 .. 300 dpi (for black ?)
542      2 .. like 1
543      3 .. 600 dpi (color&black)
544      4 .. 1200 dpi
545      5 .. ? like 1
546 */
547 
548 #define LXM_Z52_HEADERSIZE 34
549 static const unsigned char outbufHeader_z52[LXM_Z52_HEADERSIZE]=
550 {
551   0x1B,0x2A,0x24,0x00,0x00,0xFF,0xFF,         /* number of packets ----     vvvvvvvvv */
552   0x01,0x01,0x01,0x1a,0x03,0x01,              /* 0x7-0xc: resolution, direction, head */
553   0x03,0x60,                                  /* 0xd-0xe HE */
554   0x04,0xe0,                                  /* 0xf-0x10  HS vertical pos */
555   0x19,0x5c,                                  /* 0x11-0x12 */
556   0x0,0x0,                                    /* 0x13-0x14  VO between packages*/
557   0x0,0x80,                                   /* 0x15-0x16 */
558   0x0,0x0,0x0,0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x0 /* 0x17-0x21 */
559 };
560 
561 #define LXM_Z42_HEADERSIZE 34
562 static const unsigned char outbufHeader_z42[LXM_Z42_HEADERSIZE]=
563 {
564   0x1B,0x2A,0x24,0x00,0x00,0x00,0x00,
565   0x01,0x01,0x01,0x18,0x00,0x01,0x00,
566   0x00,0x00,0x00,0x00,0x00,0x00,0x00,
567   0x00,0x00,0x00,0x00,0x00,0x00,0x00,
568   0x00,0x00,0x00,0x00,0x00,0x00
569 };
570 
571 
572 static const lexmark_res_t_array lexmark_reslist_z52 =  /* LEXM_RES_COUNT entries are allowed !! */
573 {
574   /*     name                                                    hres vres softw v_pass overs unidir resid */
575   { "300x600dpi",     N_ ("300 DPI x 600 DPI"),	                 300,  600,  0,    1,    1,    0,    DPI300 },
576   { "600dpi",	      N_ ("600 DPI"),		      	         600,  600,  0,    1,    1,    0,    DPI600 },
577   { "600hq",	      N_ ("600 DPI high quality"),	         600,  600,  1,    4,    1,    0,    DPI600 },
578   { "600uni",	      N_ ("600 DPI Unidirectional"),	         600,  600,  0,    1,    1,    1,    DPI600 },
579   { "1200dpi",	      N_ ("1200 DPI"),		                1200, 1200,  1,    1,    1,    0,    DPI1200},
580   { "1200hq",	      N_ ("1200 DPI high quality"),             1200, 1200,  1,    1,    1,    0,    DPI300 },
581   { "1200hq2",	      N_ ("1200 DPI highest quality"),          1200, 1200,  1,    1,    1,    0,    DPI600 },
582   { "1200uni",	      N_ ("1200 DPI  Unidirectional"),          1200, 1200,  0,    1,    1,    1,    DPI1200},
583   { "2400x1200dpi",   N_ ("2400 DPI x 1200 DPI"),	        2400, 1200,  1,    1,    1,    0,    DPI1200},
584   { "2400x1200hq",    N_ ("2400 DPI x 1200 DPI high quality"),  2400, 1200,  1,    1,    1,    0,    DPI600 },
585   { "2400x1200hq2",   N_ ("2400 DPI x 1200 DPI highest quality"),2400, 1200,  1,    1,    1,    0,    DPI300},
586 #ifdef DEBUG
587   { "testprint",      N_ ("test print"),                        1200, 1200,  1,    1,    1,    0,    DPItest},
588 #endif
589   { "",			"", 0, 0, 0, 0, 0, -1 }
590 };
591 
592 
593 static const lexmark_inkname_t ink_types_z52[] =
594 {
595   /*   output_type   ncolors used_colors   pass_length  v_top_head_offset
596    *                                                        h_cartridge_offset
597    *                                                           h_direction_offset
598    *                                                               head_offset */
599   { "CMYK",     N_("Four Color Standard"),
600     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },
601      { 4, COLOR_MODE_CMYK,   192/3,   0, 0, 10, head_offset_cmyk }}},
602   { "RGB",      N_("Three Color Composite"),
603     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },  /* we ignore CMY, use black */
604      { 4, COLOR_MODE_CMY,    192/3,   0, 0, 10, head_offset_cmy }}},
605   { "PhotoCMYK", N_("Six Color Photo"),
606     {{ 1, COLOR_MODE_K,      192/3,   0, 0, 10, head_offset_cCmMyk },
607      { 6, COLOR_MODE_CcMcYK, 192/3,   0, 0, 10, head_offset_cCmMyk }}},
608   { "PhotoCMY", N_("Five Color Photo Composite"),
609     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cCmMyk },
610      { 5, COLOR_MODE_CcMcY,  192/3,   0, 0, 10, head_offset_cCmMyk }}}, /* we ignore CMY, use black */
611   { "Gray",     N_("Black"),
612     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },
613      { 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk }}},
614   { NULL, NULL }
615 };
616 
617 
618 
619 /*
620  * 3200 specific stuff
621  */
622 #define LXM3200_LEFTOFFS 6254
623 #define LXM3200_RIGHTOFFS (LXM3200_LEFTOFFS-2120)
624 
625 static int lxm3200_headpos = 0;
626 static int lxm3200_linetoeject = 0;
627 
628 #define LXM_3200_HEADERSIZE 24
629 static const char outbufHeader_3200[LXM_3200_HEADERSIZE] =
630 {
631   0x1b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632   0x1b, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633   0x1b, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
634 };
635 
636 static inline int
lexmark_calc_3200_checksum(unsigned char * data)637 lexmark_calc_3200_checksum(unsigned char *data)
638 {
639   int ck, i;
640 
641   ck = 0;
642   for(i=1; i<7; i++)ck += data[i];
643 
644   return(ck & 255);
645 }
646 
647 
648 static const lexmark_res_t_array lexmark_reslist_3200 =   /* LEXM_RES_COUNT entries are allowed !! */
649 {
650   /*     name                                                    hres vres softw v_pass overs unidir resid */
651   { "300x600dpi",     N_ ("300 DPI x 600 DPI"),	                 300,  600,  0,    1,    1,    0,    DPI300 },
652   { "600dpi",	      N_ ("600 DPI"),		      	         600,  600,  0,    1,    1,    0,    DPI600 },
653   { "600hq",	      N_ ("600 DPI high quality"),	         600,  600,  1,    4,    1,    0,    DPI600 },
654   { "600uni",	      N_ ("600 DPI Unidirectional"),	         600,  600,  0,    1,    1,    1,    DPI600 },
655   { "1200dpi",	      N_ ("1200 DPI"),		                1200, 1200,  1,    1,    1,    0,    DPI1200},
656   { "1200hq",	      N_ ("1200 DPI high quality"),             1200, 1200,  1,    1,    1,    0,    DPI300 },
657   { "1200hq2",	      N_ ("1200 DPI highest quality"),          1200, 1200,  1,    1,    1,    0,    DPI600 },
658   { "1200uni",	      N_ ("1200 DPI  Unidirectional"),          1200, 1200,  0,    1,    1,    1,    DPI1200},
659   { "",			"", 0, 0, 0, 0, 0, -1 }
660 };
661 
662 
663 static const lexmark_inkname_t ink_types_3200[] =
664 {
665   /*   output_type   ncolors used_colors   pass_length  v_top_head_offset
666    *                                                        h_cartridge_offset
667    *                                                           h_direction_offset
668    *                                                               head_offset */
669   { "CMYK",     N_("Four Color Standard"),
670     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cmyk },
671      { 4, COLOR_MODE_CMYK,   192/3,   0, 0, 12, head_offset_cmyk }}},
672   { "RGB",      N_("Three Color Composite"),
673     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cmyk },  /* we ignore CMY, use black */
674      { 4, COLOR_MODE_CMY,    192/3,   0, 0, 12, head_offset_cmy }}},
675   { "PhotoCMYK", N_("Six Color Photo"),
676     {{ 1, COLOR_MODE_K,      192/3,   0, 0, 12, head_offset_cCmMyk },
677      { 6, COLOR_MODE_CcMcYK, 192/3,   0, 0, 12, head_offset_cCmMyk }}},
678   { "PhotoCMY", N_("Five Color Photo Composite"),
679     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cCmMyk }, /* we ignore CMY, use black */
680      { 5, COLOR_MODE_CcMcY,  192/3,   0, 0, 12, head_offset_cCmMyk }}},
681   { NULL, NULL }
682 };
683 
684 
685 
686 
687 
688 /* main structure */
689 static const lexmark_cap_t lexmark_model_capabilities[] =
690 {
691   /* default settings for unknown models */
692 
693   {   (Lex_model)-1, 8*72,11*72,180,180,20,20,20,20, LEXMARK_INK_K, LEXMARK_SLOT_ASF1, 0 },
694 
695   /* tested models */
696 
697   { /* Lexmark z52 */
698     m_z52,
699     618, 936,         /* max paper size *//* 8.58" x 13 " */
700     INCH(2), INCH(4), /* min paper size */
701     2400, 1200, 2, /* max resolution */
702     0, 0, 5, 15, /* 15 36 border l,r,t,b    unit is 1/72 DPI */
703     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
704     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
705     LEXMARK_CAP_DMT,
706     /*** printer internal parameters ***/
707     20,        /* real left paper border */
708     123,       /* real top paper border */
709     2400,      /* horizontal resolution of 2400 dpi for positioning */
710     1200,      /* use a vertical resolution of 1200 dpi for positioning */
711     &lexmark_reslist_z52,  /* resolution specific parameters of z52 */
712     ink_types_z52,  /* supported inks */
713     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
714   },
715   { /* Lexmark z42 */
716     m_z42,
717     618, 936,         /* max paper size *//* 8.58" x 13 " */
718     INCH(2), INCH(4), /* min paper size */
719     2400, 1200, 2, /* max resolution */
720     0, 0, 5, 41, /* border l,r,t,b    unit is 1/72 DPI */
721     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
722     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
723     LEXMARK_CAP_DMT,
724     /*** printer internal parameters ***/
725     20,        /* real left paper border */
726     123,       /* real top paper border */
727     2400,      /* horizontal resolution of 2400 dpi for positioning */
728     1200,      /* use a vertical resolution of 1200 dpi for positioning */
729     &lexmark_reslist_z52,  /* resolution specific parameters of z52 */
730     ink_types_z52,  /* supported inks */
731     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
732   },
733   { /* Lexmark 3200 */
734     m_3200,
735     618, 936,      /* 8.58" x 13 " */
736     INCH(2), INCH(4), /* min paper size */
737     1200, 1200, 2,
738     11, 9, 10, 18,
739     LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
740     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
741     LEXMARK_CAP_DMT,
742     /*** printer internal parameters ***/
743     0,         /* real left paper border */
744     300,       /* real top paper border */
745     1200,      /* horizontal resolution of ?? dpi for positioning */
746     1200,      /* use a vertical resolution of 1200 dpi for positioning */
747     &lexmark_reslist_3200,  /* resolution specific parameters of 3200 */
748     ink_types_3200,  /* supported inks */
749     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
750   },
751   { /*  */
752     m_lex7500,
753     618, 936,      /* 8.58" x 13 " */
754     INCH(2), INCH(4), /* min paper size */
755     2400, 1200, 2,
756     11, 9, 10, 18,
757     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
758     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
759     LEXMARK_CAP_DMT,
760     /*** printer internal parameters ***/
761     0,         /* real left paper border */
762     300,       /* real top paper border */
763     1200,      /* horizontal resolution of ??? dpi for positioning */
764     1200,      /* use a vertical resolution of 1200 dpi for positioning */
765     &lexmark_reslist_3200,  /* resolution specific parameters of ?? */
766     ink_types_3200,  /* supported inks */
767     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
768   },
769 };
770 
771 
772 
773 
774 
775 typedef struct lexm_privdata_weave {
776   const lexmark_inkparam_t *ink_parameter;
777   int           bidirectional; /* tells us if we are allowed to print bidirectional */
778   int           direction;     /* stores the last direction or print head */
779   int		hoffset;
780   int model;
781   int width;
782   int ydpi;
783   int xdpi;
784   int physical_xdpi;
785   int last_pass_offset;
786   int jets;
787   int bitwidth;
788   int ncolors;
789   int horizontal_weave;
790   unsigned char *outbuf;
791 } lexm_privdata_weave;
792 
793 
794 /*
795  * internal functions
796  */
model_to_index(int model)797 static int model_to_index(int model)
798 {
799   int i;
800   int models= sizeof(lexmark_model_capabilities) / sizeof(lexmark_cap_t);
801   for (i=0; i<models; i++) {
802     if (lexmark_model_capabilities[i].model == model) {
803       return i;
804     }
805   }
806   return -1;
807 }
808 
809 
810 static const lexmark_cap_t *
lexmark_get_model_capabilities(const stp_vars_t * v,int model)811 lexmark_get_model_capabilities(const stp_vars_t *v, int model)
812 {
813   int i = model_to_index(model);
814 
815   if (i != -1) {
816     return &(lexmark_model_capabilities[i]);
817   }
818   stp_dprintf(STP_DBG_LEXMARK, v,
819 	       "lexmark: model %d not found in capabilities list.\n",model);
820   return &(lexmark_model_capabilities[0]);
821 }
822 
823 
824 
825 typedef struct
826 {
827   const char *name;
828   const char *text;
829   int paper_feed_sequence;
830   int platen_gap;
831   double base_density;
832   double k_lower_scale;
833   double k_upper;
834   double cyan;
835   double magenta;
836   double yellow;
837   double p_cyan;
838   double p_magenta;
839   double p_yellow;
840   double saturation;
841   double gamma;
842   int feed_adjustment;
843   int vacuum_intensity;
844   int paper_thickness;
845   const char *hue_adjustment;
846   const char *lum_adjustment;
847   const char *sat_adjustment;
848 } paper_t;
849 
850 
851 
852 static const paper_t lexmark_paper_list[] =
853 {
854   { "Plain", N_("Plain Paper"),
855     1, 0, 0.80, .1, .5, 1.0, 1.0, 1.0, .9, 1.05, 1.15,
856     1, 1.0, 0x6b, 0x1a, 0x01,
857     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
858   { "GlossyFilm", N_("Glossy Film"),
859     3, 0, 1.00 ,1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
860     1, 1.0, 0x6d, 0x00, 0x01,
861     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
862   { "Transparency", N_("Transparencies"),
863     3, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
864     1.0, 1.0, 0x6d, 0x00, 0x02,
865     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
866   { "Envelope", N_("Envelopes"),
867     4, 0, 0.80, .125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
868     1, 1.0, 0x6b, 0x1a, 0x01,
869     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
870   { "Matte", N_("Matte Paper"),
871     7, 0, 0.85, 1.0, .999, 1.05, .9, 1.05, .9, 1.0, 1.1,
872     1, 1.0, 0x00, 0x00, 0x02,
873     standard_hue_adjustment, standard_sat_adjustment, standard_sat_adjustment},
874   { "Inkjet", N_("Inkjet Paper"),
875     7, 0, 0.85, .25, .6, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
876     1, 1.0, 0x6b, 0x1a, 0x01,
877     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
878   { "Coated", N_("Photo Quality Inkjet Paper"),
879     7, 0, 1.00, 1.0, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
880     1, 1.0, 0x6b, 0x1a, 0x01,
881     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
882   { "Photo", N_("Photo Paper"),
883     8, 0, 1.00, 1.0, .9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
884     1, 1.0, 0x67, 0x00, 0x02,
885     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
886   { "GlossyPhoto", N_("Premium Glossy Photo Paper"),
887     8, 0, 1.10, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.03, 1.0,
888     1, 1.0, 0x80, 0x00, 0x02,
889     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
890   { "Luster", N_("Premium Luster Photo Paper"),
891     8, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
892     1.0, 1.0, 0x80, 0x00, 0x02,
893     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
894   { "GlossyPaper", N_("Photo Quality Glossy Paper"),
895     6, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
896     1.0, 1.0, 0x6b, 0x1a, 0x01,
897     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
898   { "Ilford", N_("Ilford Heavy Paper"),
899     8, 0, .85, .5, 1.35, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
900     1, 1.0, 0x80, 0x00, 0x02,
901     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
902   { "Other", N_("Other"),
903     0, 0, 0.80, 0.125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
904     1, 1.0, 0x6b, 0x1a, 0x01,
905     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
906 };
907 
908 static const int paper_type_count = sizeof(lexmark_paper_list) / sizeof(paper_t);
909 
910 static const lexmark_inkname_t *
lexmark_get_ink_type(const char * name,int printing_color,const lexmark_cap_t * caps)911 lexmark_get_ink_type(const char *name, int printing_color, const lexmark_cap_t * caps)
912 {
913   int i = 0;
914   const lexmark_inkname_t *ink_type = caps->ink_types;
915 
916   if (name)
917     for (i=0; ((ink_type[i].name != NULL) &&
918 	       (strcmp(name, ink_type[i].name)  != 0)); i++) ;
919   return &(ink_type[i]);
920 
921 }
922 
923 static const lexmark_inkparam_t *
lexmark_get_ink_parameter(const char * name,int printing_color,const lexmark_cap_t * caps,const stp_vars_t * nv)924 lexmark_get_ink_parameter(const char *name, int printing_color, const lexmark_cap_t * caps, const stp_vars_t *nv)
925 {
926   const lexmark_inkname_t *ink_type = lexmark_get_ink_type(name, printing_color, caps);
927 
928   if (ink_type->name == NULL) {
929     return (NULL); /* not found ! */
930   }
931 
932   return &(ink_type->ink_parameter[printing_color]);
933 }
934 
935 
936 static const paper_t *
get_media_type(const char * name,const lexmark_cap_t * caps)937 get_media_type(const char *name, const lexmark_cap_t * caps)
938 {
939   int i;
940   if (name)
941     {
942       for (i = 0; i < paper_type_count; i++)
943 	{
944 	  if (!strcmp(name, lexmark_paper_list[i].name))
945 	    return &(lexmark_paper_list[i]);
946 	}
947     }
948   return NULL;
949 }
950 
951 #pragma GCC diagnostic push
952 #pragma GCC diagnostic ignored "-Wunused-function"
953 #pragma GCC diagnostic ignored "-Wpedantic"
954 static inline int
lexmark_source_type(const stp_vars_t * v,const char * name,const lexmark_cap_t * caps)955 lexmark_source_type(const stp_vars_t *v, const char *name, const lexmark_cap_t * caps)
956 {
957   if (name)
958     {
959       if (!strcmp(name,"Auto"))    return 4;
960       if (!strcmp(name,"Manual"))    return 0;
961       if (!strcmp(name,"ManualNP")) return 1;
962     }
963 
964   stp_dprintf(STP_DBG_LEXMARK, v,
965 	       "lexmark: Unknown source type '%s' - reverting to auto\n",name);
966 
967   return 4;
968 }
969 #pragma GCC diagnostic pop
970 
971 
972 
973 /*******************************
974 lexmark_head_offset
975 *******************************/
976 static const lexmark_lineoff_t *
lexmark_head_offset(const stp_vars_t * v,int ydpi,const char * ink_type,const lexmark_cap_t * caps,const lexmark_inkparam_t * ink_parameter,lexmark_lineoff_t * lineoff_buffer)977 lexmark_head_offset(const stp_vars_t *v,
978 		    int ydpi,                       /* i */
979 		    const char *ink_type,           /* i */
980 		    const lexmark_cap_t * caps,     /* i */
981 		    const lexmark_inkparam_t *ink_parameter, /* i */
982 		    lexmark_lineoff_t *lineoff_buffer)  /* o */
983 {
984   int i;
985 
986   stp_dprintf(STP_DBG_LEXMARK, v, "  size %d,  size_v %d, size_v[0] %d\n", (int)sizeof(*lineoff_buffer), (int)sizeof(lineoff_buffer->v), (int)sizeof(lineoff_buffer->v[0]));
987   memcpy(lineoff_buffer, ink_parameter->head_offset, sizeof(*lineoff_buffer));
988 
989   for (i=0; i < (sizeof(lineoff_buffer->v) / sizeof(lineoff_buffer->v[0])); i++) {
990     lineoff_buffer->v[i] /= (caps->y_raster_res / ydpi);
991   }
992   return (lineoff_buffer);
993 }
994 
995 
996 #if 0
997 /*******************************
998 lexmark_size_type
999 *******************************/
1000 /* This method is actually not used.
1001    Is there a possibility to set such value ???????????? */
1002 static unsigned char
1003 lexmark_size_type(const stp_vars_t *v, const lexmark_cap_t * caps)
1004 {
1005   const stp_papersize_t *pp = stpi_get_papersize_by_size(v, stp_get_page_height(v),
1006 							stp_get_page_width(v));
1007   if (pp)
1008     {
1009       const char *name = pp->name;
1010       /* built ins: */
1011       if (!strcmp(name,"A5"))		return 0x01;
1012       if (!strcmp(name,"A4"))		return 0x03;
1013       if (!strcmp(name,"B5"))		return 0x08;
1014       if (!strcmp(name,"Letter"))	return 0x0d;
1015       if (!strcmp(name,"Legal"))	return 0x0f;
1016       if (!strcmp(name,"COM10"))	return 0x16;
1017       if (!strcmp(name,"DL"))		return 0x17;
1018       if (!strcmp(name,"LetterExtra"))	return 0x2a;
1019       if (!strcmp(name,"A4Extra"))	return 0x2b;
1020       if (!strcmp(name,"w288h144"))	return 0x2d;
1021       /* custom */
1022 
1023       stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: Unknown paper size '%s' - using custom\n",name);
1024     } else {
1025       stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: Couldn't look up paper size %dx%d - "
1026 	      "using custom\n",stp_get_page_height(v), stp_get_page_width(v));
1027     }
1028   return 0;
1029 }
1030 #endif
1031 
1032 
lexmark_get_phys_resolution_vertical(int model)1033 static int lexmark_get_phys_resolution_vertical(int model)
1034 {
1035   return 600;
1036 }
1037 
1038 #if 0
1039 static int lexmark_get_phys_resolution_horizontal(int model)
1040 {
1041   return 1200;
1042 }
1043 #endif
1044 
1045 static const lexmark_res_t
lexmark_get_resolution_para(const stp_vars_t * v,int model,const char * resolution)1046 *lexmark_get_resolution_para(const stp_vars_t *v, int model, const char *resolution)
1047 {
1048   const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, model);
1049 
1050   const lexmark_res_t *res = *(caps->res_parameters); /* get the resolution specific parameters of printer */
1051 
1052   if (resolution)
1053     {
1054       while (res->hres)
1055 	{
1056 	  if ((res->vres <= caps->max_ydpi) && (caps->max_ydpi != -1) &&
1057 	      (res->hres <= caps->max_xdpi) && (caps->max_xdpi != -1) &&
1058 	      (!strcmp(resolution, res->name)))
1059 	    {
1060 	      return res;
1061 	    }
1062 	  res++;
1063 	}
1064     }
1065   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark_get_resolution_para: resolution not found (%s)\n", resolution);
1066   return NULL;
1067 }
1068 
1069 
1070 static int
lexmark_print_bidirectional(const stp_vars_t * v,int model,const char * resolution)1071 lexmark_print_bidirectional(const stp_vars_t *v, int model, const char *resolution)
1072 {
1073   const lexmark_res_t *res_para = lexmark_get_resolution_para(v, model, resolution);
1074   return !res_para->unidirectional;
1075 }
1076 
1077 static const char *
lexmark_lum_adjustment(const lexmark_cap_t * caps,const stp_vars_t * v)1078 lexmark_lum_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
1079 {
1080   return (caps->lum_adjustment);
1081 }
1082 
1083 static const char *
lexmark_hue_adjustment(const lexmark_cap_t * caps,const stp_vars_t * v)1084 lexmark_hue_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
1085 {
1086   return (caps->hue_adjustment);
1087 }
1088 
1089 static const char *
lexmark_sat_adjustment(const lexmark_cap_t * caps,const stp_vars_t * v)1090 lexmark_sat_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
1091 {
1092   return (caps->sat_adjustment);
1093 }
1094 
1095 
1096 static void
lexmark_describe_resolution(const stp_vars_t * v,stp_resolution_t * x,stp_resolution_t * y)1097 lexmark_describe_resolution(const stp_vars_t *v,
1098 			    stp_resolution_t *x, stp_resolution_t *y)
1099 {
1100   const char *resolution = stp_get_string_parameter(v, "Resolution");
1101   const lexmark_res_t *res =
1102     lexmark_get_resolution_para(v, stp_get_model_id(v), resolution);
1103 
1104   if (res)
1105     {
1106       *x = res->hres;
1107       *y = res->vres;
1108       return;
1109     }
1110   *x = -1;
1111   *y = -1;
1112 }
1113 
1114 
1115 static stp_param_string_t media_sources[] =
1116 {
1117   { "Auto",		N_("Auto Sheet Feeder") },
1118   { "Manual",		N_("Manual with Pause") },
1119   { "ManualNP",		N_("Manual without Pause") }
1120 };
1121 
1122 
1123 /*
1124  * 'lexmark_parameters()' - Return the parameter values for the given parameter.
1125  */
1126 
1127 static stp_parameter_list_t
lexmark_list_parameters(const stp_vars_t * v)1128 lexmark_list_parameters(const stp_vars_t *v)
1129 {
1130   stp_parameter_list_t *ret = stp_parameter_list_create();
1131   stp_parameter_list_t *tmp_list;
1132 
1133   int i;
1134 
1135   /* Set up dithering */
1136   tmp_list = stp_dither_list_parameters(v);
1137   stp_parameter_list_append(ret, tmp_list);
1138   stp_parameter_list_destroy(tmp_list);
1139 
1140   for (i = 0; i < the_parameter_count; i++)
1141     stp_parameter_list_add_param(ret, &(the_parameters[i]));
1142   for (i = 0; i < float_parameter_count; i++)
1143     stp_parameter_list_add_param(ret, &(float_parameters[i].param));
1144   return ret;
1145 }
1146 
1147 static const char *
lexmark_describe_output(const stp_vars_t * v)1148 lexmark_describe_output(const stp_vars_t *v)
1149 {
1150   int printing_color = 0;
1151   int model = stp_get_model_id(v);
1152   const lexmark_cap_t *caps = lexmark_get_model_capabilities(v, model);
1153   const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
1154   const char *ink_type = stp_get_string_parameter(v, "InkType");
1155   const lexmark_inkparam_t *ink_parameter;
1156 
1157   if (!print_mode || strcmp(print_mode, "Color") == 0)
1158     printing_color = 1;
1159 
1160   ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
1161 
1162   if (!ink_parameter || ink_parameter->used_colors == COLOR_MODE_K ||
1163       caps->inks == LEXMARK_INK_K || !printing_color)
1164     return "Grayscale";
1165   else if (!(ink_parameter->used_colors & COLOR_MODE_K))
1166     return "CMY";
1167   else
1168     return "CMYK";
1169 }
1170 
1171 static void
lexmark_parameters(const stp_vars_t * v,const char * name,stp_parameter_t * description)1172 lexmark_parameters(const stp_vars_t *v, const char *name,
1173 		   stp_parameter_t *description)
1174 {
1175   int		i;
1176 
1177   const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, stp_get_model_id(v));
1178   description->p_type = STP_PARAMETER_TYPE_INVALID;
1179 
1180   if (name == NULL)
1181     return;
1182 
1183   for (i = 0; i < float_parameter_count; i++)
1184     if (strcmp(name, float_parameters[i].param.name) == 0)
1185       {
1186 	stp_fill_parameter_settings(description,
1187 				    &(float_parameters[i].param));
1188 	description->deflt.dbl = float_parameters[i].defval;
1189 	description->bounds.dbl.upper = float_parameters[i].max;
1190 	description->bounds.dbl.lower = float_parameters[i].min;
1191 	return;
1192       }
1193 
1194   for (i = 0; i < the_parameter_count; i++)
1195     if (strcmp(name, the_parameters[i].name) == 0)
1196       {
1197 	stp_fill_parameter_settings(description, &(the_parameters[i]));
1198 	break;
1199       }
1200 
1201   if (strcmp(name, "PageSize") == 0)
1202   {
1203     unsigned int height_limit, width_limit;
1204     unsigned int min_height_limit, min_width_limit;
1205     const stp_papersize_list_t *paper_sizes = stpi_get_standard_papersize_list();
1206     const stp_papersize_list_item_t *ptli =
1207       stpi_papersize_list_get_start(paper_sizes);
1208     description->bounds.str = stp_string_list_create();
1209 
1210     width_limit  = caps->max_paper_width;
1211     height_limit = caps->max_paper_height;
1212     min_width_limit  = caps->min_paper_width;
1213     min_height_limit = caps->min_paper_height;
1214 
1215     while (ptli)
1216       {
1217 	const stp_papersize_t *pt = stpi_paperlist_item_get_data(ptli);
1218 
1219 	if (pt->paper_size_type == PAPERSIZE_TYPE_STANDARD ||
1220 	    pt->paper_size_type == PAPERSIZE_TYPE_ENVELOPE) {
1221 
1222 	  if (strlen(pt->name) > 0 &&
1223 	      pt->width <= width_limit && pt->height <= height_limit &&
1224 	      (pt->height >= min_height_limit || pt->height == 0) &&
1225 	      (pt->width >= min_width_limit || pt->width == 0))
1226 	    {
1227 	      if (stp_string_list_count(description->bounds.str) == 0)
1228 		description->deflt.str = pt->name;
1229 	      stp_string_list_add_string(description->bounds.str,
1230 					 pt->name, gettext(pt->text));
1231 	    }
1232 	}
1233 	ptli = stpi_paperlist_item_next(ptli);
1234     }
1235   }
1236   else if (strcmp(name, "Resolution") == 0)
1237   {
1238     const lexmark_res_t *res;
1239     description->bounds.str = stp_string_list_create();
1240 
1241     res =  *(caps->res_parameters); /* get resolution specific parameters of printer */
1242 
1243     /* check for allowed resolutions */
1244     while (res->hres)
1245       {
1246 	if (stp_string_list_count(description->bounds.str) == 0)
1247 	  description->deflt.str = res->name;
1248 	stp_string_list_add_string(description->bounds.str,
1249 				  res->name, gettext(res->text));
1250 	res++;
1251       }
1252   }
1253   else if (strcmp(name, "InkType") == 0)
1254   {
1255     description->bounds.str = stp_string_list_create();
1256     description->deflt.str = caps->ink_types[0].name;
1257     for (i = 0; caps->ink_types[i].name != NULL; i++)
1258       stp_string_list_add_string(description->bounds.str,
1259 			       caps->ink_types[i].name,
1260 			       gettext(caps->ink_types[i].text));
1261   }
1262   else if (strcmp(name, "MediaType") == 0)
1263   {
1264     description->bounds.str = stp_string_list_create();
1265     description->deflt.str = lexmark_paper_list[0].name;
1266     for (i = 0; i < paper_type_count; i++)
1267       stp_string_list_add_string(description->bounds.str,
1268 			       lexmark_paper_list[i].name,
1269 			       gettext(lexmark_paper_list[i].text));
1270   }
1271   else if (strcmp(name, "InputSlot") == 0)
1272   {
1273     description->bounds.str = stp_string_list_create();
1274     description->deflt.str = media_sources[0].name;
1275     for (i = 0; i < sizeof(media_sources) / sizeof(stp_param_string_t); i++)
1276       stp_string_list_add_string(description->bounds.str,
1277 			       media_sources[i].name,
1278 			       gettext(media_sources[i].name));
1279   }
1280   else if (strcmp(name, "InkChannels") == 0)
1281     {
1282       if (caps->inks & LEXMARK_INK_CcMmYyK)
1283 	description->deflt.integer = 7;
1284       else if (caps->inks & LEXMARK_INK_CcMmYK)
1285 	description->deflt.integer = 6;
1286       else if (caps->inks & LEXMARK_INK_CMYK)
1287 	description->deflt.integer = 4;
1288       else if (caps->inks & LEXMARK_INK_CMY)
1289 	description->deflt.integer = 3;
1290       else
1291 	description->deflt.integer = 1;
1292       description->bounds.integer.lower = -1;
1293       description->bounds.integer.upper = -1;
1294     }
1295   else if (strcmp(name, "PrintingMode") == 0)
1296     {
1297       description->bounds.str = stp_string_list_create();
1298       if (caps->inks != LEXMARK_INK_K)
1299 	stp_string_list_add_string
1300 	  (description->bounds.str, "Color", _("Color"));
1301       stp_string_list_add_string
1302 	(description->bounds.str, "BW", _("Black and White"));
1303       description->deflt.str =
1304 	stp_string_list_param(description->bounds.str, 0)->name;
1305     }
1306 }
1307 
1308 /*
1309  * 'lexmark_imageable_area()' - Return the imageable area of the page.
1310  */
1311 
1312 static void
internal_imageable_area(const stp_vars_t * v,int use_paper_margins,stp_dimension_t * left,stp_dimension_t * right,stp_dimension_t * bottom,stp_dimension_t * top)1313 internal_imageable_area(const stp_vars_t *v,   /* I */
1314 			int  use_paper_margins,
1315 			stp_dimension_t  *left,	/* O - Left position in points */
1316 			stp_dimension_t  *right,	/* O - Right position in points */
1317 			stp_dimension_t  *bottom,	/* O - Bottom position in points */
1318 			stp_dimension_t  *top)	/* O - Top position in points */
1319 {
1320   stp_dimension_t	width, length;			/* Size of page */
1321   stp_dimension_t left_margin = 0;
1322   stp_dimension_t right_margin = 0;
1323   stp_dimension_t bottom_margin = 0;
1324   stp_dimension_t top_margin = 0;
1325   const char *media_size = stp_get_string_parameter(v, "PageSize");
1326   const stp_papersize_t *pt = NULL;
1327   const lexmark_cap_t *caps =
1328     lexmark_get_model_capabilities(v, stp_get_model_id(v));
1329 
1330 
1331   if (media_size && use_paper_margins)
1332     pt = stp_describe_papersize(v, media_size);
1333 
1334   stp_default_media_size(v, &width, &length);
1335   if (pt)
1336     {
1337       left_margin = pt->left;
1338       right_margin = pt->right;
1339       bottom_margin = pt->bottom;
1340       top_margin = pt->top;
1341     }
1342   left_margin = max(left_margin, caps->border_left);
1343   right_margin = max(right_margin, caps->border_right);
1344   top_margin = max(top_margin, caps->border_top);
1345   bottom_margin = max(bottom_margin, caps->border_bottom);
1346 
1347   *left =	left_margin;
1348   *right =	width - right_margin;
1349   *top =	top_margin;
1350   *bottom =	length - bottom_margin;
1351 }
1352 
1353 static void
lexmark_imageable_area(const stp_vars_t * v,stp_dimension_t * left,stp_dimension_t * right,stp_dimension_t * bottom,stp_dimension_t * top)1354 lexmark_imageable_area(const stp_vars_t *v,   /* I */
1355 		       stp_dimension_t  *left,	/* O - Left position in points */
1356 		       stp_dimension_t  *right,	/* O - Right position in points */
1357 		       stp_dimension_t  *bottom,	/* O - Bottom position in points */
1358 		       stp_dimension_t  *top)	/* O - Top position in points */
1359 {
1360   internal_imageable_area(v, 1, left, right, bottom, top);
1361 }
1362 
1363 static void
lexmark_limit(const stp_vars_t * v,stp_dimension_t * width,stp_dimension_t * height,stp_dimension_t * min_width,stp_dimension_t * min_height)1364 lexmark_limit(const stp_vars_t *v,  		/* I */
1365 	      stp_dimension_t *width,
1366 	      stp_dimension_t *height,
1367 	      stp_dimension_t *min_width,
1368 	      stp_dimension_t *min_height)
1369 {
1370   const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, stp_get_model_id(v));
1371   *width =	caps->max_paper_width;
1372   *height =	caps->max_paper_height;
1373   *min_width =  caps->min_paper_width;
1374   *min_height = caps->min_paper_height;
1375 }
1376 
1377 
1378 
1379 static int
lexmark_init_printer(const stp_vars_t * v,const lexmark_cap_t * caps,int printing_color,const char * source_str,int xdpi,int ydpi,int page_width,int page_height,int top,int left,int use_dmt)1380 lexmark_init_printer(const stp_vars_t *v, const lexmark_cap_t * caps,
1381 		     int printing_color,
1382 		     const char *source_str,
1383 		     int xdpi, int ydpi,
1384 		     int page_width, int page_height,
1385 		     int top, int left,
1386 		     int use_dmt)
1387 {
1388 
1389   /* because the details of the header sequence are not known, we simply write it as one image. */
1390 
1391 #define LXM_Z52_STARTSIZE 0x35
1392   /* 300 dpi */
1393   unsigned char startHeader_z52[LXM_Z52_STARTSIZE]={0x1b,0x2a,0x81,0x00,0x1c,0x56,0x49,0x00,
1394 					   0x01,0x00,0x2c,0x01,0x00,0x00,0x60,0x09,
1395 					   0xe4,0x0c,0x01,0x00,0x34,0x00,0x00,0x00,
1396 					   0x08,0x00,0x08,0x00,0x1b,0x2a,0x07,0x76,
1397 					   0x01,0x1b,0x2a,0x07,0x73,0x30,0x1b,0x2a,
1398 					   0x6d,0x00,0x14,0x01,0xf4,0x02,0x00,0x01,
1399 					   0xf0,0x1b,0x2a,0x07,0x63};
1400 
1401 #define LXM_Z42_STARTSIZE 0x30
1402   /* 600 dpi */
1403   unsigned char startHeader_z42[LXM_Z42_STARTSIZE]={0x1B,0x2A,0x81,0x00,0x1C,0x50,0x41,0x00,
1404 					   0x01,0x00,0x58,0x02,0x04,0x00,0xC0,0x12,
1405 					   0xC8,0x19,0x02,0x00,0x50,0x00,0x14,0x00,
1406 					   0x07,0x00,0x08,0x00,0x1B,0x2A,0x07,0x73,
1407 					   0x30,0x1B,0x2A,0x6D,0x00,0x14,0x01,0xC0,
1408 					   0x02,0x00,0x01,0xBE,0x1B,0x2A,0x07,0x63};
1409 
1410   #define ESC2a "\033\052"
1411 
1412 
1413 
1414 #define LXM_3200_STARTSIZE 32
1415 
1416   unsigned char startHeader_3200[LXM_3200_STARTSIZE] =
1417   {
1418     0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1419     0x1b, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
1420     0x1b, 0x30, 0x80, 0x0C, 0x02, 0x00, 0x00, 0xbe,
1421     0x1b, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21
1422   };
1423 
1424   /* write init sequence */
1425   switch(caps->model)
1426 	{
1427 		case m_z52:
1428 			stp_zfwrite((const char *) startHeader_z52,
1429 				    LXM_Z52_STARTSIZE,1,v);
1430 #ifdef DEBUG
1431 			lex_write_tmp_file(dbgfileprn, (void *)startHeader_z52, LXM_Z52_STARTSIZE);
1432 #endif
1433 			break;
1434 
1435 		case m_z42:
1436 			stp_zfwrite((const char *) startHeader_z42,
1437 				    LXM_Z42_STARTSIZE,1,v);
1438 #ifdef DEBUG
1439 			lex_write_tmp_file(dbgfileprn, (void *)startHeader_z42, LXM_Z42_STARTSIZE);
1440 #endif
1441 			break;
1442 
1443 		case m_3200:
1444 			stp_zfwrite((const char *) startHeader_3200,
1445 				    LXM_3200_STARTSIZE, 1, v);
1446 			break;
1447 
1448 		default:
1449 			stp_eprintf(v, "Unknown printer !! %i\n", caps->model);
1450 			return 0;
1451   }
1452 
1453 
1454 
1455   /*
1456   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: printable size = %dx%d (%dx%d) %02x%02x %02x%02x\n",
1457 	  page_width,page_height,printable_width,printable_length,
1458 	  arg_70_1,arg_70_2,arg_70_3,arg_70_4);
1459   */
1460   return 1;
1461 }
1462 
lexmark_deinit_printer(const stp_vars_t * v,const lexmark_cap_t * caps)1463 static void lexmark_deinit_printer(const stp_vars_t *v, const lexmark_cap_t * caps)
1464 {
1465 
1466 	switch(caps->model)	{
1467 		case m_z52:
1468 		{
1469 			char buffer[40];
1470 
1471 			memcpy(buffer, ESC2a, 2);
1472 			buffer[2] = 0x7;
1473 			buffer[3] = 0x65;
1474 
1475 			stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: <<eject page.>> %x %x %x %x\n", buffer[0],  buffer[1], buffer[2], buffer[3]);
1476 #ifdef DEBUG
1477 			lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 4);
1478 #endif
1479 			/* eject page */
1480 			stp_zfwrite(buffer, 1, 4, v);
1481 		}
1482 		break;
1483 
1484 		case m_z42:
1485 		{
1486 			unsigned char buffer[12] = {0x1B,0x2A,0x07,0x65,0x1B,0x2A,0x82,0x00,0x00,0x00,0x00,0xAC};
1487 			stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: <<eject page.>>\n");
1488 #ifdef DEBUG
1489 			lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 12);
1490 #endif
1491 			/* eject page */
1492 			stp_zfwrite((char *)buffer, 1, 12, v);
1493 		}
1494 		break;
1495 
1496 		case m_3200:
1497 		{
1498 		  unsigned char buffer[24] =
1499 		  {
1500 		    0x1b, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1501 		    0x1b, 0x31, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
1502 		    0x1b, 0x33, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33
1503 		  };
1504 
1505 			stp_dprintf(STP_DBG_LEXMARK, v, "Headpos: %d\n", lxm3200_headpos);
1506 
1507 			lxm3200_linetoeject += 2400;
1508 			buffer[3] = lxm3200_linetoeject >> 8;
1509 			buffer[4] = lxm3200_linetoeject & 0xff;
1510 			buffer[7] = lexmark_calc_3200_checksum(&buffer[0]);
1511 			buffer[11] = lxm3200_headpos >> 8;
1512 			buffer[12] = lxm3200_headpos & 0xff;
1513 			buffer[15] = lexmark_calc_3200_checksum(&buffer[8]);
1514 
1515 			stp_zfwrite((const char *)buffer, 24, 1, v);
1516 		}
1517 		break;
1518 
1519 		case m_lex7500:
1520 			break;
1521 	}
1522 
1523 }
1524 
1525 
1526 /* paper_shift() -- shift paper in printer -- units are unknown :-)
1527  */
paper_shift(const stp_vars_t * v,int offset,const lexmark_cap_t * caps)1528 static void paper_shift(const stp_vars_t *v, int offset, const lexmark_cap_t * caps)
1529 {
1530 	switch(caps->model)	{
1531 		case m_z52:
1532 		case m_z42:
1533 		{
1534 			unsigned char buf[5] = {0x1b, 0x2a, 0x3, 0x0, 0x0};
1535 			if(offset == 0)return;
1536 			buf[3] = (unsigned char)(offset >> 8);
1537 			buf[4] = (unsigned char)(offset & 0xFF);
1538 			stp_zfwrite((const char *)buf, 1, 5, v);
1539 #ifdef DEBUG
1540 			lex_write_tmp_file(dbgfileprn, (void *)buf, 5);
1541 #endif
1542 		}
1543 		break;
1544 
1545 		case m_3200:
1546 		{
1547 			unsigned char buf[8] = {0x1b, 0x23, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00};
1548 			if(offset == 0)return;
1549 			lxm3200_linetoeject -= offset;
1550 			buf[3] = (unsigned char)(offset >> 8);
1551 			buf[4] = (unsigned char)(offset & 0xff);
1552 			buf[7] = lexmark_calc_3200_checksum(buf);
1553 			stp_zfwrite((const char *)buf, 1, 8, v);
1554 		}
1555 		break;
1556 
1557 		case m_lex7500:
1558 			break;
1559 	}
1560 
1561 	stp_dprintf(STP_DBG_LEXMARK, v, "Lines to eject: %d\n", lxm3200_linetoeject);
1562 }
1563 
1564 /*
1565  * 'advance_buffer()' - Move (num) lines of length (len) down one line
1566  *                      and sets first line to 0s
1567  *                      accepts NULL pointers as buf
1568  *                  !!! buf must contain more than (num) lines !!!
1569  *                      also sets first line to 0s if num<1
1570  */
1571 #if 0
1572 static void
1573 lexmark_advance_buffer(unsigned char *buf, int len, int num)
1574 {
1575   if (!buf || !len) return;
1576   if (num>0) memmove(buf+len,buf,len*num);
1577   memset(buf,0,len);
1578 }
1579 #endif
1580 
1581 static double
get_double_param(stp_vars_t * v,const char * param)1582 get_double_param(stp_vars_t *v, const char *param)
1583 {
1584   if (param && stp_check_float_parameter(v, param, STP_PARAMETER_ACTIVE))
1585     return stp_get_float_parameter(v, param);
1586   else
1587     return 1.0;
1588 }
1589 
1590 /**********************************************************
1591  * lexmark_print() - Print an image to a LEXMARK printer.
1592  **********************************************************/
1593 /* This method should not be printer dependent (maybe it is because of nozzle count and other things) */
1594 /* The method will set the printing method depending on the selected printer.
1595    It will define the colors to be used and the resolution.
1596    Additionally the pass_length will be defined.
1597    The method lexmark_write() is responsible to handle the received lines
1598    in a correct way.
1599 */
1600 static int
lexmark_do_print(stp_vars_t * v,stp_image_t * image)1601 lexmark_do_print(stp_vars_t *v, stp_image_t *image)
1602 {
1603   int		status = 1;
1604   int		y;		/* Looping vars */
1605   stp_resolution_t	xdpi, ydpi;	/* Resolution */
1606   stp_dimension_t page_width,	/* Width of page */
1607     page_height,	/* Length of page */
1608     page_left,
1609     page_top,
1610     page_right,
1611     page_bottom,
1612     page_true_width,	/* True length of page */
1613     page_true_height;	/* True length of page */
1614   int
1615     out_width,	/* Width of image on page in pixels */
1616     out_height,	/* Length of image on page */
1617     length,		/* Length of raster data in bytes*/
1618     buf_length,     /* Length of raster data buffer (dmt) */
1619     errdiv,		/* Error dividend */
1620     errmod,		/* Error modulus */
1621     errval,		/* Current error value */
1622     errline,	/* Current raster line */
1623     errlast;	/* Last raster line loaded */
1624   unsigned      zero_mask;
1625   int           image_height;
1626   int           use_dmt = 0;
1627   int pass_length=0;              /* count of inkjets for one pass */
1628   int add_top_offset=0;              /* additional top offset */
1629   int printMode = 0;
1630   /* Lexmark do not have different pixel sizes. We have to correct the density according the print resolution. */
1631   double  densityDivisor;            /* This parameter is will adapt the density according the resolution */
1632   double k_lower, k_upper;
1633   int  physical_xdpi = 0;
1634   int  physical_ydpi = 0;
1635   int i;
1636 
1637   stp_curve_t *lum_adjustment = NULL;
1638   stp_curve_t *hue_adjustment = NULL;
1639   stp_curve_t *sat_adjustment = NULL;
1640 
1641   /* weave parameters */
1642   lexmark_linebufs_t cols;
1643   int  nozzle_separation;
1644   int  horizontal_passes;
1645   int  ncolors;
1646   lexm_privdata_weave privdata;
1647 
1648   lexmark_lineoff_t lineoff_buffer;  /* holds the line offsets of each color */
1649 #ifdef DEBUG
1650   testdata td;
1651 #endif
1652 
1653 
1654   int		model         = stp_get_model_id(v);
1655   const char	*resolution   = stp_get_string_parameter(v, "Resolution");
1656   const char	*media_type   = stp_get_string_parameter(v, "MediaType");
1657   const char	*media_source = stp_get_string_parameter(v, "InputSlot");
1658   const char    *print_mode = stp_get_string_parameter(v, "PrintingMode");
1659   int printing_color = 0;
1660   const char	*ink_type     = stp_get_string_parameter(v, "InkType");
1661   stp_dimension_t	top = stp_get_top(v);
1662   stp_dimension_t	left = stp_get_left(v);
1663 
1664   const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, model);
1665   const lexmark_res_t *res_para_ptr =
1666     lexmark_get_resolution_para(v, model, resolution);
1667   const paper_t *media = get_media_type(media_type,caps);
1668   const lexmark_inkparam_t *ink_parameter;
1669 
1670 #ifdef DEBUG
1671   dbgfileprn = lex_open_tmp_file(); /* open file with xx */
1672 #endif
1673 
1674   if (!stp_verify(v))
1675     {
1676       stp_eprintf(v, "Print options not verified; cannot print.\n");
1677       return 0;
1678     }
1679   if (strcmp(print_mode, "Color") == 0)
1680     printing_color = 1;
1681 
1682   ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
1683 
1684   if (ink_parameter == NULL)
1685     {
1686       stp_eprintf(v, "Illegal Ink Type specified; cannot print.\n");
1687       return 0;
1688     }
1689 
1690   stp_image_init(image);
1691 
1692   /* force grayscale if image is grayscale
1693    *                 or single black cartridge installed
1694    */
1695 
1696   if ((ink_parameter->used_colors == COLOR_MODE_K) ||
1697       (caps->inks == LEXMARK_INK_K))
1698     {
1699       printing_color = 0;
1700       stp_set_string_parameter(v, "PrintingMode", "BW");
1701     }
1702 
1703   /*
1704    * Choose the correct color conversion function...
1705    */
1706 
1707 
1708   ncolors = ink_parameter->ncolors;
1709   printMode = ink_parameter->used_colors;
1710   pass_length = ink_parameter->pass_length;
1711   add_top_offset = ink_parameter->v_top_head_offset;
1712 
1713 
1714   /*
1715    * Figure out the output resolution...
1716    */
1717 
1718   stp_describe_resolution(v, &xdpi, &ydpi);
1719   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: resolution=%dx%d\n",(int)xdpi,(int)ydpi);
1720 
1721   switch (res_para_ptr->resid) {
1722   case DPI300:
1723     physical_xdpi = 300;
1724     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
1725     break;
1726   case DPI600:
1727     physical_xdpi = 600;
1728     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
1729     break;
1730   case DPI1200:
1731   case DPItest:
1732     physical_xdpi = 1200;
1733     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
1734     break;
1735   default:
1736     return 0;
1737     break;
1738   }
1739   /* adapt the density */
1740   densityDivisor = ((xdpi / 300)*(ydpi/ 600));
1741 
1742 #ifdef DEBUG
1743   if (res_para_ptr->resid == DPItest) {
1744     stp_dprintf(STP_DBG_LEXMARK, v, "Start test print1\n");
1745     doTestPrint = 1;
1746   }
1747 #endif
1748 
1749   if ((printMode & COLOR_MODE_PHOTO) == COLOR_MODE_PHOTO) {
1750     /* in case of photo mode we have to go a bit lighter */
1751 densityDivisor /= 1.2;
1752   }
1753 
1754   nozzle_separation = ydpi / physical_ydpi;
1755 
1756   horizontal_passes = xdpi / physical_xdpi;
1757   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: horizontal_passes %i, xdpi %d, physical_xdpi %i\n",
1758 	      horizontal_passes, (int)xdpi, physical_xdpi);
1759 
1760 
1761 
1762 
1763   if (!strcmp(resolution+(strlen(resolution)-3),"DMT") &&
1764       (caps->features & LEXMARK_CAP_DMT)) {
1765     use_dmt= 1;
1766     stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: using drop modulation technology\n");
1767   }
1768 
1769   /*
1770   * Compute the output size...
1771   */
1772 
1773   out_width = stp_get_width(v);
1774   out_height = stp_get_height(v);
1775 
1776   internal_imageable_area(v, 0, &page_left, &page_right,
1777 			  &page_bottom, &page_top);
1778   left -= page_left;
1779   top -= page_top;
1780   page_width = page_right - page_left;
1781   page_height = page_bottom - page_top;
1782 
1783   stp_dprintf(STP_DBG_LEXMARK, v, "page_right %f, page_left %f, page_top %f, page_bottom %f, left %f, top %f\n",page_right, page_left, page_top, page_bottom,left, top);
1784 
1785   image_height = stp_image_height(image);
1786 
1787   stp_default_media_size(v, &page_true_width, &page_true_height);
1788   lxm3200_linetoeject = (page_true_height * 1200) / 72;
1789 
1790 
1791   if (!lexmark_init_printer(v, caps, printing_color,
1792 			    media_source,
1793 			    xdpi, ydpi, page_width, page_height,
1794 			    top,left,use_dmt))
1795     return 0;
1796 
1797   /*
1798   * Convert image size to printer resolution...
1799   */
1800 
1801   out_width  = xdpi * out_width / 72;
1802   out_height = ydpi * out_height / 72;
1803 
1804 
1805   stp_dprintf(STP_DBG_LEXMARK, v, "border: left %f, x_raster_res %d, offset_left %d\n", left, caps->x_raster_res, caps->offset_left_border);
1806 
1807   left = ((caps->x_raster_res * left) / 72) + caps->offset_left_border;
1808 
1809   stp_dprintf(STP_DBG_LEXMARK, v, "border: left %f\n", left);
1810 
1811 
1812 
1813 #ifdef DEBUG
1814   if (doTestPrint == 1) {
1815     stp_dprintf(STP_DBG_LEXMARK, v, "Start test print\n");
1816     testprint(&td);
1817     out_width = td.x;
1818     out_height = td.y;
1819     if (td.cols != 7) {
1820     printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y;
1821     } else {
1822     printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_LM | COLOR_MODE_LC;
1823     }
1824   }
1825 #endif
1826 
1827  /*
1828   * Allocate memory for the raster data...
1829   */
1830 
1831   length = (out_width + 7) / 8;
1832 
1833 
1834 
1835   if (use_dmt) {
1836     /*    buf_length= length*2; */
1837     buf_length= length;
1838   } else {
1839     buf_length= length;
1840   }
1841 
1842   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: buflength is %d!\n",buf_length);
1843 
1844 
1845   /* Now we know the color which are used, let's get the memory for every color image */
1846   cols.p.k = NULL;
1847   cols.p.c = NULL;
1848   cols.p.y = NULL;
1849   cols.p.m = NULL;
1850   cols.p.C = NULL;
1851   cols.p.M = NULL;
1852   cols.p.Y = NULL;
1853 
1854 
1855   if ((printMode & COLOR_MODE_C) == COLOR_MODE_C) {
1856     cols.p.c = stp_zalloc(buf_length+10);
1857   }
1858   if ((printMode & COLOR_MODE_Y) == COLOR_MODE_Y) {
1859     cols.p.y = stp_zalloc(buf_length+10);
1860   }
1861   if ((printMode & COLOR_MODE_M) == COLOR_MODE_M) {
1862     cols.p.m = stp_zalloc(buf_length+10);
1863   }
1864   if ((printMode & COLOR_MODE_K) == COLOR_MODE_K) {
1865     cols.p.k = stp_zalloc(buf_length+10);
1866   }
1867   if ((printMode & COLOR_MODE_LC) == COLOR_MODE_LC) {
1868     cols.p.C = stp_zalloc(buf_length+10);
1869   }
1870   if ((printMode & COLOR_MODE_LY) == COLOR_MODE_LY) {
1871     cols.p.Y = stp_zalloc(buf_length+10);
1872   }
1873   if ((printMode & COLOR_MODE_LM) == COLOR_MODE_LM) {
1874     cols.p.M = stp_zalloc(buf_length+10);
1875   }
1876 
1877   if (cols.p.k)
1878     {
1879       if (cols.p.c)
1880 	stp_set_string_parameter(v, "STPIOutputType", "KCMY");
1881       else
1882 	stp_set_string_parameter(v, "STPIOutputType", "Grayscale");
1883     }
1884   else
1885     stp_set_string_parameter(v, "STPIOutputType", "CMY");
1886 
1887   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: driver will use colors %c%c%c%c%c%c%c\n",
1888 	      (cols.p.c) ? 'c' : ' ',
1889 	      (cols.p.C) ? 'C' : ' ',
1890 	      (cols.p.m) ? 'm' : ' ',
1891 	      (cols.p.M) ? 'M' : ' ',
1892 	      (cols.p.y) ? 'y' : ' ',
1893 	      (cols.p.Y) ? 'Y' : ' ',
1894 	      (cols.p.k) ? 'k' : ' ');
1895 
1896   /* initialize soft weaving */
1897   privdata.ink_parameter = ink_parameter;
1898   privdata.bidirectional = lexmark_print_bidirectional(v, model, resolution);
1899   privdata.outbuf = stp_malloc((((((pass_length/8)*11))+40) * out_width)+2000);
1900   privdata.direction = 0;
1901   stp_allocate_component_data(v, "Driver", NULL, NULL, &privdata);
1902   /*  lxm_nozzles_used = 1;*/
1903 
1904   stp_initialize_weave(v,
1905 		       pass_length, /* jets */
1906 		       nozzle_separation, /* separation */
1907 		       horizontal_passes, /* h oversample */
1908 		       res_para_ptr->vertical_passes, /* v passes */
1909 		       res_para_ptr->vertical_oversample, /* v oversample */
1910 		       ncolors, /* colors */
1911 		       1, /* bits/pixel */
1912 		       out_width, /* line width */
1913 		       out_height,
1914 		       ((top * ydpi) / 72)+(((caps->offset_top_border+add_top_offset)*ydpi)
1915 					    /caps->y_raster_res),
1916 		       (page_height * ydpi) / 72,
1917 		       (const int *) lexmark_head_offset(v, ydpi, ink_type, caps, ink_parameter, &lineoff_buffer),
1918 		       STP_WEAVE_ZIGZAG, /* weave_strategy */
1919 		       flush_pass,
1920 		       stp_fill_uncompressed,  /* fill_start */
1921 		       stp_pack_uncompressed,  /* pack */
1922 		       stp_compute_uncompressed_linewidth);  /* compute_linewidth */
1923   privdata.last_pass_offset = 0;
1924   privdata.jets = pass_length;
1925   privdata.ncolors = ncolors;
1926   privdata.horizontal_weave = horizontal_passes;
1927 
1928 
1929   if (!stp_check_float_parameter(v, "Density", STP_PARAMETER_DEFAULTED))
1930     {
1931       stp_set_float_parameter_active(v, "Density", STP_PARAMETER_ACTIVE);
1932       stp_set_float_parameter(v, "Density", 1.0);
1933     }
1934 
1935   stp_dprintf(STP_DBG_LEXMARK, v, "density is %f\n",
1936 	      stp_get_float_parameter(v, "Density"));
1937 
1938   stp_dprintf(STP_DBG_LEXMARK, v, "density is %f and will be changed to %f  (%f)\n",
1939 		stp_get_float_parameter(v, "Density"),
1940 		stp_get_float_parameter(v, "Density") / densityDivisor,
1941 		densityDivisor);
1942 
1943   /* Lexmark do not have different pixel sizes. We have to correct the density according the print resolution. */
1944   stp_scale_float_parameter(v, "Density", 1.0 / densityDivisor);
1945 
1946 
1947   /*
1948    * Compute the LUT.  For now, it's 8 bit, but that may eventually
1949    * sometimes change.
1950    */
1951   if (ncolors > 4)
1952     k_lower = .5;
1953   else
1954     k_lower = .25;
1955 
1956   if (media)
1957     {
1958       stp_scale_float_parameter(v, "Density", media->base_density);
1959       stp_scale_float_parameter(v, "Cyan", media->p_cyan);
1960       stp_scale_float_parameter(v, "Magenta", media->p_magenta);
1961       stp_scale_float_parameter(v, "Yellow", media->p_yellow);
1962       k_lower *= media->k_lower_scale;
1963       k_upper  = media->k_upper;
1964     }
1965   else
1966     {
1967       stp_scale_float_parameter(v, "Density", .8);
1968       k_lower *= .1;
1969       k_upper = .5;
1970     }
1971   if (stp_get_float_parameter(v, "Density") > 1.0)
1972     stp_set_float_parameter(v, "Density", 1.0);
1973 
1974   stp_dprintf(STP_DBG_LEXMARK, v, "density is %f\n",stp_get_float_parameter(v, "Density"));
1975 
1976 
1977   if (!stp_check_float_parameter(v, "GCRLower", STP_PARAMETER_ACTIVE))
1978     stp_set_default_float_parameter(v, "GCRLower", k_lower);
1979   if (!stp_check_float_parameter(v, "GCRUpper", STP_PARAMETER_ACTIVE))
1980     stp_set_default_float_parameter(v, "GCRUpper", k_upper);
1981   stp_dither_init(v, image, out_width, xdpi, ydpi);
1982 
1983 	/*
1984 	  stpi_dither_set_black_lower(dither, .8 / ((1 << (use_dmt+1)) - 1));*/
1985   /*stpi_dither_set_black_levels(dither, 0.5, 0.5, 0.5);
1986     stpi_dither_set_black_lower(dither, 0.4);*/
1987   /*
1988     if (use_glossy_film)
1989   */
1990   if (cols.p.k)
1991     {
1992       stp_dither_add_channel(v, cols.p.k, STP_ECOLOR_K, 0);
1993       stp_channel_set_black_channel(v, STP_ECOLOR_K);
1994     }
1995   if (cols.p.c)
1996     stp_dither_add_channel(v, cols.p.c, STP_ECOLOR_C, 0);
1997   if (cols.p.C)
1998     stp_dither_add_channel(v, cols.p.C, STP_ECOLOR_C, 1);
1999   if (cols.p.m)
2000     stp_dither_add_channel(v, cols.p.m, STP_ECOLOR_M, 0);
2001   if (cols.p.M)
2002     stp_dither_add_channel(v, cols.p.M, STP_ECOLOR_M, 1);
2003   if (cols.p.y)
2004     stp_dither_add_channel(v, cols.p.y, STP_ECOLOR_Y, 0);
2005   if (cols.p.Y)
2006     stp_dither_add_channel(v, cols.p.Y, STP_ECOLOR_Y, 1);
2007 
2008   if (!use_dmt) {
2009     if (cols.p.C)
2010       {
2011 	stp_dither_set_inks_full(v, STP_ECOLOR_C, 2, photo_dither_shades, 1.0,
2012 				  0.31 / .5);
2013       }
2014     if (cols.p.M)
2015       {
2016 	stp_dither_set_inks_full(v, STP_ECOLOR_M, 2, photo_dither_shades, 1.0,
2017 				  0.61 / .97);
2018       }
2019     if (cols.p.Y)
2020       {
2021 	stp_dither_set_inks_full(v, STP_ECOLOR_Y, 2, photo_dither_shades, 1.0,
2022 				  0.08);
2023       }
2024   }
2025 
2026   stp_channel_set_density_adjustment(v, STP_ECOLOR_K, 0,
2027 				     get_double_param(v, "BlackDensity") *
2028 				     get_double_param(v, "Density"));
2029   stp_channel_set_density_adjustment(v, STP_ECOLOR_C, 0,
2030 				     get_double_param(v, "CyanDensity") *
2031 				     get_double_param(v, "Density"));
2032   stp_channel_set_density_adjustment(v, STP_ECOLOR_M, 0,
2033 				     get_double_param(v, "MagentaDensity") *
2034 				     get_double_param(v, "Density"));
2035   stp_channel_set_density_adjustment(v, STP_ECOLOR_Y, 0,
2036 				     get_double_param(v, "YellowDensity") *
2037 				     get_double_param(v, "Density"));
2038   if (!use_dmt) {
2039     if (cols.p.C)
2040       {
2041 	stp_channel_set_density_adjustment
2042 	  (v, STP_ECOLOR_C, 1, (get_double_param(v, "CyanDensity") *
2043 			    get_double_param(v, "LightCyanTrans") *
2044 			    get_double_param(v, "Density")));
2045       }
2046     if (cols.p.M)
2047       {
2048 	stp_channel_set_density_adjustment
2049 	  (v, STP_ECOLOR_M, 1, (get_double_param(v, "MagentaDensity") *
2050 			    get_double_param(v, "LightMagentaTrans") *
2051 			    get_double_param(v, "Density")));
2052       }
2053     if (cols.p.Y)
2054       {
2055 	stp_channel_set_density_adjustment
2056 	  (v, STP_ECOLOR_Y, 1, (get_double_param(v, "YellowDensity") *
2057 			    get_double_param(v, "LightYellowTrans") *
2058 			    get_double_param(v, "Density")));
2059       }
2060   }
2061 
2062   /*
2063    * Output the page...
2064   */
2065 
2066   if (!stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_ACTIVE) &&
2067       media->hue_adjustment)
2068     {
2069       hue_adjustment = stp_read_and_compose_curves
2070 	(lexmark_hue_adjustment(caps, v),
2071 	 media ? media->hue_adjustment : NULL, STP_CURVE_COMPOSE_ADD, 384);
2072       stp_set_curve_parameter(v, "HueMap", hue_adjustment);
2073       stp_curve_destroy(hue_adjustment);
2074     }
2075   if (!stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_ACTIVE) &&
2076       media->lum_adjustment)
2077     {
2078       lum_adjustment = stp_read_and_compose_curves
2079 	(lexmark_lum_adjustment(caps, v),
2080 	 media ? media->lum_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
2081       stp_set_curve_parameter(v, "LumMap", lum_adjustment);
2082       stp_curve_destroy(lum_adjustment);
2083     }
2084   if (!stp_check_curve_parameter(v, "SatMap", STP_PARAMETER_ACTIVE) &&
2085       media->sat_adjustment)
2086     {
2087       sat_adjustment = stp_read_and_compose_curves
2088 	(lexmark_sat_adjustment(caps, v),
2089 	 media ? media->sat_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
2090       stp_set_curve_parameter(v, "SatMap", sat_adjustment);
2091       stp_curve_destroy(sat_adjustment);
2092     }
2093 
2094   (void) stp_color_init(v, image, 65536);
2095 
2096   /* calculate the memory we need for one line of the printer image (hopefully we are right) */
2097   stp_dprintf(STP_DBG_LEXMARK, v, "---------- buffer mem size = %d\n", (((((pass_length/8)*11)/10)+40) * out_width)+200);
2098 
2099   errdiv  = image_height / out_height;
2100   errmod  = image_height % out_height;
2101   errval  = 0;
2102   errlast = -1;
2103   errline  = 0;
2104 
2105   privdata.hoffset = left;
2106   privdata.ydpi = ydpi;
2107   privdata.model = model;
2108   privdata.width = out_width;
2109   privdata.xdpi = xdpi;
2110   privdata.physical_xdpi = physical_xdpi;
2111   privdata.bitwidth = 1;
2112 
2113   for (y = 0; y < out_height; y ++)
2114     {
2115       int duplicate_line = 1;
2116 
2117       if (errline != errlast)
2118 	{
2119 	  errlast = errline;
2120 	  duplicate_line = 0;
2121 	  if (stp_color_get_row(v, image, errline, &zero_mask))
2122 	    {
2123 	      status = 2;
2124 	      break;
2125 	    }
2126 	}
2127       stp_dither(v, y, duplicate_line, zero_mask, NULL);
2128       stp_write_weave(v, (unsigned char **)cols.v);
2129 
2130       errval += errmod;
2131       errline += errdiv;
2132       if (errval >= out_height)
2133 	{
2134 	  errval -= out_height;
2135 	  errline ++;
2136 	}
2137     }
2138   stp_image_conclude(image);
2139 
2140   stp_flush_all(v);
2141 
2142   lexmark_deinit_printer(v, caps);
2143 
2144   /*
2145   * Cleanup...
2146   */
2147   if (privdata.outbuf != NULL) {
2148     stp_free(privdata.outbuf);/* !!!!!!!!!!!!!! */
2149   }
2150 
2151   for (i = 0; i < NCHANNELS; i++)
2152     if (cols.v[i])
2153       stp_free(cols.v[i]);
2154 
2155 #ifdef DEBUG
2156   lex_tmp_file_deinit(dbgfileprn);
2157 #endif
2158 
2159   return status;
2160 }
2161 
2162 static int
lexmark_print(const stp_vars_t * v,stp_image_t * image)2163 lexmark_print(const stp_vars_t *v, stp_image_t *image)
2164 {
2165   int status;
2166   stp_vars_t *nv = stp_vars_create_copy(v);
2167   stp_prune_inactive_options(nv);
2168   status = lexmark_do_print(nv, image);
2169   stp_vars_destroy(nv);
2170   return status;
2171 }
2172 
2173 static const stp_printfuncs_t print_lexmark_printfuncs =
2174 {
2175   lexmark_list_parameters,
2176   lexmark_parameters,
2177   stp_default_media_size,
2178   lexmark_imageable_area,
2179   lexmark_imageable_area,
2180   lexmark_limit,
2181   lexmark_print,
2182   lexmark_describe_resolution,
2183   lexmark_describe_output,
2184   stp_verify_printer_params,
2185   NULL,
2186   NULL,
2187   NULL,
2188   stpi_standard_describe_papersize
2189 };
2190 
2191 
2192 
2193 /* lexmark_init_line
2194    This method is printer type dependent code.
2195 
2196    This method initializes the line to be printed. It will set
2197    the printer specific initialization which has to be done before
2198    the pixels of the image could be printed.
2199 */
2200 static unsigned char *
lexmark_init_line(const stp_vars_t * v,int mode,unsigned char * prnBuf,int pass_length,int offset,int width,int direction,const lexmark_inkparam_t * ink_parameter,const lexmark_cap_t * caps)2201 lexmark_init_line(const stp_vars_t *v,
2202 		  int mode, unsigned char *prnBuf,
2203 		  int pass_length,
2204 		  int offset,    /* offset from left in 1/"x_raster_res" DIP (printer resolution)*/
2205 		  int width, int direction,
2206 		  const lexmark_inkparam_t *ink_parameter,
2207 		  const lexmark_cap_t *   caps	        /* I - Printer model */
2208 		  )
2209 {
2210   int pos1 = 0;
2211   int pos2 = 0;
2212   int abspos, disp;
2213   int hend = 0;
2214   int header_size = 0;
2215 
2216 
2217   /*  stp_eprintf(v, "#### width %d, length %d, pass_length %d\n", width, length, pass_length);*/
2218   /* first, we write the line header */
2219   switch(caps->model)  {
2220   case m_z52:
2221   case m_z42:
2222     if (caps->model == m_z52)
2223       {
2224 	header_size = LXM_Z52_HEADERSIZE;
2225 	memcpy(prnBuf, outbufHeader_z52, header_size);
2226       }
2227     if (caps->model == m_z42)
2228       {
2229 	header_size = LXM_Z42_HEADERSIZE;
2230 	memcpy(prnBuf, outbufHeader_z42, LXM_Z42_HEADERSIZE);
2231       }
2232 
2233     /* K could only be present if black is printed only. */
2234     if ((mode & COLOR_MODE_K) || (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM))) {
2235       stp_dprintf(STP_DBG_LEXMARK, v, "set  photo/black cartridge \n");
2236       prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_BLACK_PRINT;
2237 
2238       if (direction) {
2239       } else {
2240 	offset += ink_parameter->h_direction_offset;
2241       }
2242     } else {
2243       stp_dprintf(STP_DBG_LEXMARK, v, "set color cartridge \n");
2244       prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_COLOR_PRINT;
2245 
2246       if (direction) {
2247 	offset += ink_parameter->h_catridge_offset;
2248       } else {
2249 	offset += ink_parameter->h_catridge_offset + ink_parameter->h_direction_offset;
2250       }
2251     }
2252 
2253     switch (mode & PRINT_MODE_MASK) {
2254     case PRINT_MODE_300:
2255       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_300_DPI;
2256       break;
2257     case PRINT_MODE_600:
2258       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_600_DPI;
2259       break;
2260     case PRINT_MODE_1200:
2261       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_1200_DPI;
2262       break;
2263     case PRINT_MODE_2400:
2264       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_2400_DPI;
2265       break;
2266     }
2267 
2268 
2269     if (direction) {
2270       prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 1;
2271     } else {
2272       prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 2;
2273     }
2274 
2275     /* set package count */
2276     prnBuf[13] = (unsigned char)((width) >> 8);
2277     prnBuf[14] = (unsigned char)((width) & 0xFF);
2278     /* set horizontal offset */
2279     prnBuf[15] =(unsigned char)(offset >> 8);
2280     prnBuf[16] =(unsigned char)(offset & 0xFF);
2281 
2282     if (caps->model == m_z42) {
2283 	switch(mode & PRINT_MODE_MASK) {
2284 	case PRINT_MODE_300:
2285 		hend = (width-1)*(2400/300);
2286 		break;
2287 	case PRINT_MODE_600:
2288 		hend = (width-1)*(2400/600);
2289 		break;
2290 	case PRINT_MODE_1200:
2291 		hend = (width-1)*(2400/1200);
2292 		break;
2293 	case PRINT_MODE_2400:
2294 		hend = (width-1)*(2400/2400);
2295 		break;
2296 	}
2297 	hend += offset;
2298 	prnBuf[17] = (unsigned char)(hend >> 8);
2299         prnBuf[18] = (unsigned char)(hend & 0xFF);
2300 
2301  	prnBuf[10] = (pass_length==208 ? 0x1A : 0x18);
2302     }
2303 
2304     return prnBuf + header_size;  /* return the position where the pixels have to be written */
2305     break;
2306     case m_3200:
2307       memcpy(prnBuf, outbufHeader_3200, LXM_3200_HEADERSIZE);
2308 
2309       offset = (offset - 60) * 4;
2310 
2311       /* K could only be present if black is printed only. */
2312       if((mode & COLOR_MODE_K) ||
2313 	 (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM)))
2314 	{
2315 	  disp = LXM3200_LEFTOFFS;
2316 	  prnBuf[2] = 0x00;
2317 	}
2318       else
2319 	{
2320 	  disp = LXM3200_RIGHTOFFS;
2321 	  prnBuf[2] = 0x80;
2322 	}
2323 
2324       if(pass_length == 208)
2325 	{
2326 	  prnBuf[2] |= 0x10;
2327 	}
2328 
2329       switch(mode & PRINT_MODE_MASK) 	{
2330 	case PRINT_MODE_300:
2331 	  prnBuf[2] |= 0x20;
2332 	  pos1 = offset + disp;
2333 	  pos2 = offset + (width * 4) + disp;
2334 	  break;
2335 
2336 	case PRINT_MODE_600:
2337 	  prnBuf[2] |= 0x00;
2338 	  pos1 = offset + disp;
2339 	  pos2 = offset + (width * 2) + disp;
2340 	  break;
2341 
2342 	case PRINT_MODE_1200:
2343 	  prnBuf[2] |= 0x40;
2344 	  pos1 = offset + disp;
2345 	  pos2 = (offset + width) + disp;
2346 	  break;
2347 	}
2348 
2349       if(direction)
2350 	prnBuf[2] |= 0x01;
2351       else
2352 	prnBuf[2] |= 0x00;
2353 
2354       /* set package count */
2355       prnBuf[3] = (unsigned char)((width) >> 8);
2356       prnBuf[4] = (unsigned char)((width) & 0xff);
2357 
2358       /* set horizontal offset */
2359       prnBuf[21] = (unsigned char)(pos1 >> 8);
2360       prnBuf[22] = (unsigned char)(pos1 & 0xFF);
2361 
2362       abspos = ((((pos2 - 3600) >> 3) & 0xfff0) + 9);
2363       prnBuf[5] = (abspos-lxm3200_headpos) >> 8;
2364       prnBuf[6] = (abspos-lxm3200_headpos) & 0xff;
2365 
2366       lxm3200_headpos = abspos;
2367 
2368       if(LXM3200_RIGHTOFFS > 4816)
2369 	abspos = (((LXM3200_RIGHTOFFS - 4800) >> 3) & 0xfff0);
2370       else
2371 	abspos = (((LXM3200_RIGHTOFFS - 3600) >> 3) & 0xfff0);
2372 
2373       prnBuf[11] = (lxm3200_headpos-abspos) >> 8;
2374       prnBuf[12] = (lxm3200_headpos-abspos) & 0xff;
2375 
2376       lxm3200_headpos = abspos;
2377 
2378       prnBuf[7] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[0]);
2379       prnBuf[15] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[8]);
2380       prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
2381 
2382       /* return the position where the pixels have to be written */
2383       return prnBuf + LXM_3200_HEADERSIZE;
2384       break;
2385 
2386   case m_lex7500:
2387     stp_eprintf(v, "Lexmark 7500 not supported !\n");
2388     return NULL;
2389     break;
2390   }
2391   return NULL;
2392 }
2393 
2394 
2395 typedef struct Lexmark_head_colors {
2396   int v_start;
2397   unsigned char *line;
2398   int head_nozzle_start;
2399   int head_nozzle_end;
2400   int used_jets;
2401 } Lexmark_head_colors;
2402 
2403 /* lexmark_write
2404    This method is has NO printer type dependent code.
2405    This method writes a single line of the print. The line consists of "pass_length"
2406    pixel lines (pixels, which could be printed with one pass by the printer.
2407 */
2408 
2409 
2410 static int
lexmark_write(const stp_vars_t * v,unsigned char * prnBuf,int * paperShift,int direction,int pass_length,const lexmark_cap_t * caps,const lexmark_inkparam_t * ink_parameter,int xdpi,int yCount,Lexmark_head_colors * head_colors,int length,int mode,int ydpi,int width,int offset,int dmt)2411 lexmark_write(const stp_vars_t *v,		/* I - Print file or command */
2412 	      unsigned char *prnBuf,      /* mem block to buffer output */
2413 	      int *paperShift,
2414 	      int direction,
2415 	      int pass_length,       /* num of inks to print */
2416 	      const lexmark_cap_t *   caps,	        /* I - Printer model */
2417 	      const lexmark_inkparam_t *ink_parameter,
2418 	      int xdpi,
2419 	      int yCount,
2420 	      Lexmark_head_colors *head_colors,
2421 	      int           length,	/* I - Length of bitmap data in bytes */
2422 	      int           mode,	/* I - Which color */
2423 	      int           ydpi,		/* I - Vertical resolution */
2424 	      int           width,	/* I - Printed width in pixels */
2425 	      int           offset, 	/* I - Offset from left side in lexmark_cap_t.x_raster_res DPI */
2426 	      int           dmt)
2427 {
2428   unsigned char *tbits=NULL, *p=NULL;
2429   int clen;
2430   int x;  /* actual vertical position */
2431   int y;  /* actual horizontal position */
2432   int dy; /* horiz. inkjet position */
2433   int x1;
2434   unsigned short pixelline;  /* byte to be written */
2435   unsigned int valid_bytes; /* bit list which tells the present bytes */
2436   int xStart=0; /* count start for horizontal line */
2437   int xEnd=0;
2438   int xIter=0;  /* count direction for horizontal line */
2439   int anyCol=0;
2440   int colIndex;
2441   int rwidth; /* real with used at printing (includes shift between even & odd nozzles) */
2442   /* stp_dprintf(STP_DBG_LEXMARK, v, "<%c>",("CMYKcmy"[coloridx])); */
2443   stp_dprintf(STP_DBG_LEXMARK, v, "pass length %d\n", pass_length);
2444 
2445 
2446   /* first, we check the length of the line an cut it if necessary. */
2447   if ((((width*caps->x_raster_res)/xdpi)+offset) > ((caps->max_paper_width*caps->x_raster_res)/72)) {
2448     /* line too long !! Cut the line */
2449    stp_dprintf(STP_DBG_LEXMARK, v, "!! Line too long !! reduce it from %d", width);
2450     width = ((((caps->max_paper_width*caps->x_raster_res)/72) - offset)*xdpi)/caps->x_raster_res;
2451    stp_dprintf(STP_DBG_LEXMARK, v, " down to %d\n", width);
2452   }
2453 
2454 
2455   /* we have to write the initial sequence for a line */
2456 
2457   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: printer line initialized.\n");
2458 
2459   if (direction) {
2460     /* left to right */
2461     xStart = -get_lr_shift(mode);
2462     xEnd = width-1;
2463     xIter = 1;
2464     rwidth = xEnd - xStart;
2465   } else {
2466     /* right to left ! */
2467     xStart = width-1;
2468     xEnd = -get_lr_shift(mode);
2469     rwidth = xStart - xEnd;
2470     xIter = -1;
2471   }
2472 
2473   p = lexmark_init_line(v, mode, prnBuf, pass_length, offset, rwidth,
2474 			direction,  /* direction */
2475 			ink_parameter, caps);
2476 
2477 
2478   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: xStart %d, xEnd %d, xIter %d.\n", xStart, xEnd, xIter);
2479 
2480   /* now we can start to write the pixels */
2481   yCount = 2;
2482 
2483 
2484   for (x=xStart; x != xEnd; x+=xIter) {
2485     int  anyDots=0; /* tells us if there was any dot to print */
2486 
2487        switch(caps->model)	{
2488 	case m_z52:
2489 	  tbits = p;
2490 	  *(p++) = 0x3F;
2491 	  tbits[1] = 0; /* here will be nice bitmap */
2492 	  p++;
2493 	  break;
2494 
2495 	case m_3200:
2496 	case m_z42:
2497 	  tbits = p;
2498 	  p += 4;
2499 	  break;
2500 
2501 	case m_lex7500:
2502 	  break;
2503 	}
2504 
2505 
2506     pixelline =0;     /* here we store 16 pixels */
2507     valid_bytes = 0;  /* for every valid word (16 bits) a corresponding bit will be set to 1. */
2508 
2509     anyDots =0;
2510     x1 = x+get_lr_shift(mode);
2511 
2512     for (colIndex=0; colIndex < 3; colIndex++) {
2513       for (dy=head_colors[colIndex].head_nozzle_start,y=head_colors[colIndex].v_start*yCount;
2514 	   (dy < head_colors[colIndex].head_nozzle_end);
2515 	   y+=yCount, dy++) { /* we start counting with 1 !!!! */
2516 	if (head_colors[colIndex].line != NULL) {
2517 	  pixelline = pixelline << 1;
2518 	  if ((x >= 0) &&
2519 	      ((dy - head_colors[colIndex].head_nozzle_start) < (head_colors[colIndex].used_jets/2)))
2520 	    pixelline = pixelline | ((head_colors[colIndex].line[(y*length)+(x/8)] >> (7-(x%8))) & 0x1);
2521 	  pixelline = pixelline << 1;
2522 	  if ((x1 < width) &&
2523 	      (((dy - head_colors[colIndex].head_nozzle_start)+1) < (head_colors[colIndex].used_jets/2)))
2524 	    pixelline = pixelline | ((head_colors[colIndex].line[(((yCount>>1)+y)*length)+ (x1/8)] >> (7-(x1%8))) & 0x1);
2525 
2526 	} else {
2527 	  pixelline = pixelline << 2;
2528 	}
2529 	switch(caps->model)		{
2530 	case m_z52:
2531 	  if ((dy%8) == 7) {
2532 	    /* we have two bytes, write them */
2533 	    anyDots |= pixelline;
2534 	    if (pixelline) {
2535 	      /* we have some dots */
2536 	      valid_bytes = valid_bytes >> 1;
2537 	      *((p++)) = (unsigned char)(pixelline >> 8);
2538 	      *((p++)) = (unsigned char)(pixelline & 0xff);
2539 	    } else {
2540 	      /* there are no dots ! */
2541 	      valid_bytes = valid_bytes >> 1;
2542 	      valid_bytes |= 0x1000;
2543 	    }
2544 	    pixelline =0;
2545 	  }
2546 	  break;
2547 
2548 	case m_3200:
2549 	case m_z42:
2550 	  if((dy % 4) == 3)
2551 	    {
2552 	      anyDots |= pixelline;
2553 	      valid_bytes <<= 1;
2554 
2555 	      if(pixelline)
2556 		*(p++) = (unsigned char)(pixelline & 0xff);
2557 	      else
2558 		valid_bytes |= 0x01;
2559 
2560 	      pixelline = 0;
2561 	    }
2562 	  break;
2563 
2564 	case m_lex7500:
2565 	  break;
2566 	}
2567       }
2568     }
2569 
2570     switch(caps->model)	{
2571     case m_z52:
2572       if (pass_length != 208) {
2573 	valid_bytes = valid_bytes >> 1;
2574 	valid_bytes |= 0x1000;
2575       }
2576       tbits[0] = 0x20 | ((unsigned char)((valid_bytes >> 8) & 0x1f));
2577       tbits[1] = (unsigned char)(valid_bytes & 0xff);
2578       break;
2579 
2580     case m_z42:
2581       if ((p-tbits) & 1) *(p++)=0; /* z42 packets always have even length */
2582       /* fall through */
2583     case m_3200:
2584       tbits[0] = 0x80 | ((unsigned char)((valid_bytes >> 24) & 0x1f));
2585       tbits[1] = (unsigned char)((valid_bytes >> 16) & 0xff);
2586       tbits[2] = (unsigned char)((valid_bytes >> 8) & 0xff);
2587       tbits[3] = (unsigned char)(valid_bytes & 0xff);
2588       break;
2589 
2590     case m_lex7500:
2591       break;
2592     }
2593 
2594 
2595     if (anyDots) {
2596       anyCol = 1;
2597     } else {
2598       /* there are no dots, make empty package */
2599       /*     stp_dprintf(STP_DBG_LEXMARK, v, "-- empty col %i\n", x); */
2600     }
2601   }
2602 
2603   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: 4\n");
2604 
2605   clen=((unsigned char *)p)-prnBuf;
2606 
2607   switch(caps->model)    {
2608     case m_z52:
2609     case m_z42:
2610   prnBuf[IDX_SEQLEN]  =(unsigned char)(clen >> 24);
2611   prnBuf[IDX_SEQLEN+1]  =(unsigned char)(clen >> 16);
2612   prnBuf[IDX_SEQLEN+2]  =(unsigned char)(clen >> 8);
2613   prnBuf[IDX_SEQLEN+3]=(unsigned char)(clen & 0xFF);
2614   break;
2615 
2616   case m_3200:
2617     prnBuf[18] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 16);
2618     prnBuf[19] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 8);
2619     prnBuf[20] = (unsigned char)((clen - LXM_3200_HEADERSIZE) & 0xff);
2620     prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
2621     break;
2622 
2623   default:
2624     break;
2625   }
2626 
2627   if (anyCol) {
2628     /* fist, move the paper */
2629     paper_shift(v, (*paperShift), caps);
2630     *paperShift=0;
2631 
2632     /* now we write the image line */
2633     stp_zfwrite((const char *)prnBuf,1,clen,v);
2634 #ifdef DEBUG
2635     lex_write_tmp_file(dbgfileprn, (void *)prnBuf,clen);
2636 #endif
2637     stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: line written.\n");
2638     return 1;
2639   } else {
2640     stp_dprintf(STP_DBG_LEXMARK, v, "-- empty line\n");
2641     return 0;
2642   }
2643 
2644   /* Send a line of raster graphics... */
2645 }
2646 
2647 
2648 
2649 #ifdef DEBUG
lex_open_tmp_file()2650 const stp_vars_t *lex_open_tmp_file() {
2651   int i;
2652   const stp_vars_t *ofile;
2653   char tmpstr[256];
2654 
2655       stp_eprintf(v, " create file !\n");
2656   for (i=0, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r");
2657        ofile != NULL;
2658        i++, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r")) {
2659     if (ofile != NULL)
2660       {
2661 	fclose(ofile);
2662       }
2663   }
2664       stp_eprintf(v, "Create file %s !\n", tmpstr);
2665   ofile = fopen(tmpstr, "wb");
2666   STPI_ASSERT(ofile);
2667   return ofile;
2668 }
2669 
lex_tmp_file_deinit(const stp_vars_t * file)2670 void lex_tmp_file_deinit(const stp_vars_t *file) {
2671   stp_eprintf(v, "Close file %lx\n", file);
2672   fclose(file);
2673 }
2674 
lex_write_tmp_file(const stp_vars_t * ofile,void * data,int length)2675 const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length) {
2676   fwrite(data, 1, length, ofile);
2677 }
2678 
2679 
2680 #endif
2681 
2682 
2683 static void
flush_pass(stp_vars_t * v,int passno,int vertical_subpass)2684 flush_pass(stp_vars_t *v, int passno, int vertical_subpass)
2685 {
2686   stp_lineoff_t        *lineoffs   = stp_get_lineoffsets_by_pass(v, passno);
2687   stp_lineactive_t     *lineactive = stp_get_lineactive_by_pass(v, passno);
2688   const stp_linebufs_t *bufs       = stp_get_linebases_by_pass(v, passno);
2689   stp_pass_t           *pass       = stp_get_pass_by_pass(v, passno);
2690   stp_linecount_t      *linecount  = stp_get_linecount_by_pass(v, passno);
2691   lexm_privdata_weave *pd =
2692     (lexm_privdata_weave *) stp_get_component_data(v, "Driver");
2693   int width = pd->width;
2694   int hoffset = pd->hoffset;
2695   int model = pd->model;
2696   int xdpi = pd->xdpi;
2697   int ydpi = pd->ydpi;
2698   int physical_xdpi = pd->physical_xdpi;
2699   int lwidth = (width + (pd->horizontal_weave - 1)) / pd->horizontal_weave;
2700   int microoffset = vertical_subpass & (pd->horizontal_weave - 1);
2701 
2702   int prn_mode;
2703   int j; /* color counter */
2704   const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, model);
2705   int paperShift;
2706   Lexmark_head_colors head_colors[3]={{0, NULL,     0,  64/2, 64},
2707 				      {0, NULL,  64/2, 128/2, 64},
2708 				      {0, NULL, 128/2, 192/2, 64}};
2709 
2710 
2711   stp_dprintf(STP_DBG_LEXMARK, v, "Lexmark: flush_pass, here we are !\n");
2712   stp_dprintf(STP_DBG_LEXMARK, v, "  passno %d, pd->ncolors %d, width %d, lwidth %d, bitwidth %d\n",
2713 	       passno, pd->ncolors, width, lwidth, pd->bitwidth);
2714   stp_dprintf(STP_DBG_LEXMARK, v, "microoffset %d, vertical_subpass %d, pd->horizontal_weave %d\n", microoffset,vertical_subpass, pd->horizontal_weave);
2715 
2716   stp_dprintf(STP_DBG_LEXMARK, v, "Lexmark: last_pass_offset %d, logicalpassstart %d\n", pd->last_pass_offset, pass->logicalpassstart);
2717   stp_dprintf(STP_DBG_LEXMARK, v, "Lexmark: vertical adapt: caps->y_raster_res %d, ydpi %d,  \n", caps->y_raster_res, ydpi);
2718 
2719   switch (physical_xdpi) {
2720   case 300:
2721     prn_mode = PRINT_MODE_300;
2722     break;
2723   case 600:
2724     prn_mode = PRINT_MODE_600;
2725     break;
2726   case 1200:
2727     prn_mode = PRINT_MODE_1200;
2728     break;
2729   default:
2730     stp_dprintf(STP_DBG_LEXMARK, v, "Error: Unsupported phys resolution (%d)\n", physical_xdpi);
2731     return;
2732     break;
2733   }
2734   /* calculate paper shift and adapt actual resolution to physical positioning resolution */
2735   paperShift = (pass->logicalpassstart - pd->last_pass_offset) * (caps->y_raster_res/ydpi);
2736   for (j = 0; j < pd->ncolors; j++)
2737     stp_dprintf(STP_DBG_LEXMARK, v, "Color %d: active %d line %p jets %d offset %ld\n",
2738 		j, lineactive[0].v[j], (void *)bufs[0].v[j], linecount[0].v[j],
2739 		lineoffs[0].v[j]);
2740 
2741       /*** do we have to print something with the color cartridge ? ***/
2742       if ((STP_ECOLOR_C < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_C] > 0))
2743 	{
2744 	  head_colors[0].line = bufs[0].v[STP_ECOLOR_C];
2745 	  head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_C];
2746 	}
2747       else
2748 	{
2749 	  head_colors[0].line = NULL;
2750 	  head_colors[0].used_jets = 0;
2751 	}
2752 
2753       if ((STP_ECOLOR_M < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_M] > 0))
2754 	{
2755 	  head_colors[1].line = bufs[0].v[STP_ECOLOR_M];
2756 	  head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_M];
2757 	}
2758       else
2759 	{
2760 	  head_colors[1].line = 0;
2761 	  head_colors[1].used_jets = 0;
2762 	}
2763 
2764       if ((STP_ECOLOR_Y < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_Y] > 0))
2765 	{
2766 	  head_colors[2].line = bufs[0].v[STP_ECOLOR_Y];
2767 	  head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_Y];
2768 	}
2769       else
2770 	{
2771 	  head_colors[2].line = 0;
2772 	  head_colors[2].used_jets = 0;
2773 	}
2774 
2775       if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
2776 
2777 
2778 
2779 	stp_dprintf(STP_DBG_LEXMARK, v, "lexmark_write: lwidth %d\n", lwidth);
2780 	lexmark_write(v,		/* I - Print file or command */
2781 		      pd->outbuf,/*unsigned char *prnBuf,   mem block to buffer output */
2782 		      &paperShift,           /* int *paperShift, */
2783 		      pd->direction,                     /* int direction, */
2784 		      pd->jets,       /* num of inks to print */
2785 		      caps,                  /* const lexmark_cap_t *   caps,	    I - Printer model */
2786 		      pd->ink_parameter,
2787 		      xdpi,                  /* int xresolution, */
2788 		      2,                     /* yCount,*/
2789 		      head_colors,           /* Lexmark_head_colors *head_colors, */
2790 		      (lwidth+7)/8, /* length,	 I - Length of bitmap data of one line in bytes */
2791 		      prn_mode | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_M,       /* mode,	 I - Which color */
2792 		      ydpi,                  /* ydpi,	 I - Vertical resolution */
2793 		      lwidth,      /* width, 	 I - Printed width in pixels*/
2794 		      hoffset+microoffset,   /* offset  I - Offset from left side in x_raster_res DPI */
2795 		      0                      /* dmt */);
2796 	if (pd->bidirectional)
2797 	  pd->direction = (pd->direction +1) & 1;
2798       }
2799 
2800 
2801       /*** do we have to print something with black or photo cartridge ? ***/
2802       /* we print with the photo or black cartridge */
2803 
2804     if (pd->jets != 208)
2805       {
2806 	/* we have photo or black cartridge */
2807 	if ((STP_ECOLOR_LC < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LC] > 0))
2808 	  {
2809 	    head_colors[0].line = bufs[0].v[STP_ECOLOR_LC];
2810 	    head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_LC];
2811 	  }
2812 	else
2813 	  {
2814 	    head_colors[0].line = 0;
2815 	    head_colors[0].used_jets = 0;
2816 	  }
2817 
2818 	    if ((STP_ECOLOR_LM < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LM] > 0))
2819 	  {
2820 	    head_colors[1].line = bufs[0].v[STP_ECOLOR_LM];
2821 	    head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_LM];
2822 	  }
2823 	else
2824 	  {
2825 	    head_colors[1].line = 0;
2826 	    head_colors[1].used_jets = 0;
2827 	  }
2828 
2829 	    if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
2830 	  {
2831 	    head_colors[2].line = bufs[0].v[STP_ECOLOR_K];
2832 	    head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_K];
2833 	  }
2834 	else
2835 	  {
2836 	    head_colors[2].line = 0;
2837 	    head_colors[2].used_jets = 0;
2838 	  }
2839       }
2840     else
2841       {
2842 	if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
2843 	  {
2844 	    /* we have black cartridge; we have to print with all 208 jets at once */
2845 	    head_colors[0].line = bufs[0].v[STP_ECOLOR_K];
2846 	    head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_K];
2847 	    head_colors[0].head_nozzle_start = 0;
2848 	    head_colors[0].head_nozzle_end = pd->jets/2;
2849 	    head_colors[2].line = NULL;
2850 	    head_colors[2].used_jets = 0;
2851 	    head_colors[2].head_nozzle_start = 0;
2852 	    head_colors[2].head_nozzle_end = 0;
2853 	    head_colors[1].line = NULL;
2854 	    head_colors[1].used_jets = 0;
2855 	    head_colors[1].head_nozzle_start = 0;
2856 	    head_colors[1].head_nozzle_end = 0;
2857 	  }
2858 	else
2859 	  {
2860 	    head_colors[2].line = NULL;
2861 	    head_colors[2].used_jets = 0;
2862 	    head_colors[2].head_nozzle_start = 0;
2863 	    head_colors[2].head_nozzle_end = 0;
2864 	    head_colors[1].line = NULL;
2865 	    head_colors[1].used_jets = 0;
2866 	    head_colors[1].head_nozzle_start = 0;
2867 	    head_colors[1].head_nozzle_end = 0;
2868 	    head_colors[0].line = NULL;
2869 	    head_colors[0].used_jets = 0;
2870 	    head_colors[0].head_nozzle_start = 0;
2871 	    head_colors[0].head_nozzle_end = 0;
2872 	  }
2873       }
2874 
2875      if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
2876 
2877     lexmark_write(v,		/* I - Print file or command */
2878 		  pd->outbuf,/*unsigned char *prnBuf,   mem block to buffer output */
2879 		  &paperShift,           /* int *paperShift, */
2880 		  pd->direction,             /* int direction, */
2881 		  pd->jets,              /* num of inks to print */
2882 		  caps,                  /* const lexmark_cap_t *   caps,     I - Printer model */
2883 		  pd->ink_parameter,
2884 		  xdpi,                  /* int xresolution, */
2885 		  2,                     /* yCount,*/
2886 		  head_colors,           /* Lexmark_head_colors *head_colors, */
2887 		  (lwidth+7)/8, /* length,	 I - Length of bitmap data of one line in bytes */
2888 		  prn_mode | COLOR_MODE_LC | COLOR_MODE_LM | COLOR_MODE_K,       /* mode,	 I - Which color */
2889 		  ydpi,                  /* ydpi,	 I - Vertical resolution */
2890 		  lwidth,      /* width, 	 I - Printed width in pixels*/
2891 		  hoffset+microoffset,   /* offset  I - Offset from left side in x_raster_res DPI */
2892 		  0                      /* dmt */);
2893     if (pd->bidirectional)
2894       {
2895 	pd->direction = (pd->direction +1) & 1;
2896       }
2897     }
2898   /* store paper position in respect if there was a paper shift */
2899   pd->last_pass_offset = pass->logicalpassstart - (paperShift / (caps->y_raster_res/ydpi));
2900 
2901   for (j = 0; j < pd->ncolors; j++)
2902     {
2903       lineoffs[0].v[j]  = 0;
2904       linecount[0].v[j] = 0;
2905     }
2906 
2907   stp_dprintf(STP_DBG_LEXMARK, v, "lexmark_write finished\n");
2908 
2909 }
2910 
2911 
2912 
2913 
2914 
2915 #ifdef DEBUG
2916 
testprint(testdata * td)2917 static void testprint(testdata *td)
2918 {
2919   int icol, i;
2920   char dummy1[256], dummy2[256];
2921   lexmark_linebufs_t linebufs;
2922 
2923   /* init */
2924   for (i=0; i < (sizeof(linebufs.v)/sizeof(linebufs.v[0])); i++) {
2925     linebufs.v[i] = NULL;
2926   }
2927 
2928   /*let's go */
2929   td->ifile = fopen("/t1.ppm", "rb");
2930   if (td->ifile != NULL) {
2931     /* find "{" */
2932     fscanf(td->ifile, "%[^{]{%[^\"]\"%d %d %d %d\",", dummy1, dummy2, &(td->x), &(td->y), &(td->cols), &(td->deep));
2933     td->cols -= 1; /* we reduce it by one because fist color will be ignored */
2934     td->input_line = (char *)stp_malloc(td->x+10);
2935     stp_eprintf(v, "<%s> <%s>\n", dummy1, dummy2);
2936     stp_eprintf(v, "%d %d %d %d\n", td->x, td->y, td->cols, td->deep);
2937     if (td->cols > 16) {
2938       stp_eprintf(v, "too many colors !!\n");
2939       return;
2940     }
2941 
2942     /* read the colors */
2943     fscanf(td->ifile, "%[^\"]\"%c	c %[^\"]\",", dummy1, dummy2, dummy2); /* jump over first color */
2944     for (icol=0; icol < td->cols; icol++) {  /* we ignore the first color. It is "no dot". */
2945       fscanf(td->ifile, "%[^\"]\"%c	c %[^\"]\",", dummy1, &(td->colchar[icol]), dummy2);
2946       stp_eprintf(v, "colchar %d <%c>\n", i, td->colchar[icol]);
2947     }
2948 
2949 
2950     if (td->cols > 5) {
2951       td->cols = 7;
2952       for (icol=0; icol < td->cols; icol++) {  /* we ignore the first color. It is "no dot". */
2953 	linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
2954       }
2955     } else if (td->cols > 4) {
2956       td->cols = 5;
2957       for (icol=0; icol < td->cols; icol++) {  /* we ignore the first color. It is "no dot". */
2958 	linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
2959       }
2960     } else {
2961       td->cols = 1;
2962       linebufs.v[0] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
2963     }
2964   } else {
2965     stp_eprintf(v, "can't open file !\n");
2966   }
2967 }
2968 
2969 
readtestprintline(testdata * td,lexmark_linebufs_t * linebufs)2970 static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs)
2971 {
2972   char dummy1[256];
2973   int icol, ix;
2974 
2975   stp_eprintf(v, "start readtestprintline\n");
2976   for (icol=0; icol < 7; icol++) {
2977     if (linebufs->v[icol] != NULL) {
2978       memset(linebufs->v[icol], 0, (td->x+7)/8);  /* clean line */
2979     }
2980   }
2981   stp_eprintf(v, "1 readtestprintline cols %d\n", td->cols);
2982 
2983 
2984   fscanf(td->ifile, "%[^\"]\"%[^\"]\",", dummy1, td->input_line);
2985   for (icol=0; icol < td->cols; icol++) {
2986    for (ix=0; ix < td->x; ix++) {
2987       if (td->input_line[ix] == td->colchar[icol]) {
2988 	/* set the dot */
2989 	if (icol != 0) {
2990 	  linebufs->v[icol-1][ix/8] |= 1 << (ix%8);
2991 	} else {
2992 	  /* this is specific, we set ymc */
2993 	  linebufs->p.y[ix/8] |= 1 << (ix%8);
2994 	  linebufs->p.m[ix/8] |= 1 << (ix%8);
2995 	  linebufs->p.c[ix/8] |= 1 << (ix%8);
2996 	}
2997       }
2998     }
2999   }
3000   /* stp_eprintf(v, "pixchar  <%s><%s>\n",dummy1, td->input_line);*/
3001 }
3002 
3003 #endif
3004 
3005 
3006 static stp_family_t print_lexmark_module_data =
3007   {
3008     &print_lexmark_printfuncs,
3009     NULL
3010   };
3011 
3012 static int
print_lexmark_module_init(void)3013 print_lexmark_module_init(void)
3014 {
3015   return stpi_family_register(print_lexmark_module_data.printer_list);
3016 }
3017 
3018 
3019 static int
print_lexmark_module_exit(void)3020 print_lexmark_module_exit(void)
3021 {
3022   return stpi_family_unregister(print_lexmark_module_data.printer_list);
3023 }
3024 
3025 
3026 /* Module header */
3027 #define stp_module_version print_lexmark_LTX_stp_module_version
3028 #define stp_module_data print_lexmark_LTX_stp_module_data
3029 
3030 stp_module_version_t stp_module_version = {0, 0};
3031 
3032 stp_module_t stp_module_data =
3033   {
3034     "lexmark",
3035     VERSION,
3036     "Lexmark family driver",
3037     STP_MODULE_CLASS_FAMILY,
3038     NULL,
3039     print_lexmark_module_init,
3040     print_lexmark_module_exit,
3041     (void *) &print_lexmark_module_data
3042   };
3043