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