1 /***************************************************************************
2     ppa.c  -  functions to handle PPA, SCP, and VLINK protocols
3                              -------------------
4     begin                : Thu Jan 13 2000
5     copyright            : (C) 1998-2000 by pnm2ppa project
6     email                :
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifdef HAVE_CONFIG_H
19 # include "config.h"
20 #endif
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 
27 #define __PPA_C__
28 
29 #include "ppa_syslog.h"
30 #include "global.h"
31 #include "ppa.h"
32 #include "debug.h"
33 #include "lang.h"
34 
35 
36 /*
37   VLink packet structure:
38 
39     Bytes  Description
40     --------------------------------------------
41       1    Packet-start marker (always '$')
42       1    Channel (0: image data, 1: commands/responses(*), 2: autostatus(*), 128: pacing(*))
43       2    Data length (N)
44       N    [remaining data (e.g., SCP or SCP2 packet when Channel=1)]
45 
46   (*): responses, autostatus, and pacing are communicated from the printer to
47        the computer, and may be safely ignored.
48 */
49 void
vlink_put(FILE * fptr,int channel,int length,void * data)50 vlink_put (FILE * fptr, int channel, int length, void *data)
51 {
52     fputc ('$', fptr);
53     fputc (channel, fptr);
54     fputc (length >> 8, fptr);
55     fputc (length & 0xFF, fptr);
56     fwrite (data, length, 1, fptr);
57 }
58 
59 /*
60   SCP packet structure:
61 
62     Bytes  Description
63     --------------------------------------------
64       2    Command specifier
65       2    Command reference number
66       1    Priority
67       1    padding? (always zero)
68       2    Data length (N)
69       N    [remaining data]
70 
71     ComSpec  ComRef     Command
72     -------------------------------
73        35       1     Initialize1
74       101       2     Initialize2
75        21       1     Initialize3
76        19       1     Handle Media
77        18       1     Print Sweep
78 */
79 void
scp_put(FILE * fptr,int comspec,int comref,int priority,int length,void * data)80 scp_put (FILE * fptr, int comspec, int comref, int priority,
81 	 int length, void *data)
82 {
83     /* encapsulate the vlink_put call in here, to avoid a memcpy */
84     fputc ('$', fptr);
85     fputc (1, fptr);
86     fputc ((length + 8) >> 8, fptr);
87     fputc ((length + 8) & 0xFF, fptr);
88 
89     fputc (comspec >> 8, fptr);
90     fputc (comspec & 0xFF, fptr);
91     fputc (comref >> 8, fptr);
92     fputc (comref & 0xFF, fptr);
93     fputc (priority, fptr);
94     fputc (0, fptr);
95     fputc (length >> 8, fptr);
96     fputc (length & 0xFF, fptr);
97 
98     fwrite (data, length, 1, fptr);
99 }
100 
101 
102 /*
103   SCP2 packet structure:
104 
105     Bytes  Description
106     --------------------------------------------
107       2    Command specifier
108       2    Packet length (N)
109       1    Priority
110       1    padding? (always zero)
111       2    Command reference number
112       4    Channel 0 buffer increment
113       4    version number? (always 00 02 00 00)
114      N-16  [remaining data]
115 
116     ComSpec  ComRef     Command
117     -------------------------------
118      0x186      1     Initialize1
119      0x18f      2     Initialize2
120      0x183      1     Initialize3
121      0x181      1     Handle Media
122      0x180      1     Print Sweep
123 */
124 void
scp2_put(FILE * fptr,unsigned short comspec,unsigned short pkt_len_s16,unsigned char priority,unsigned short comref,unsigned data_len,void * data)125 scp2_put (FILE * fptr, unsigned short comspec,
126 	  unsigned short pkt_len_s16,
127 	  unsigned char priority, unsigned short comref,
128 	  unsigned data_len, void *data)
129 {
130     /* encapsulate the vlink_put call in here, to avoid a memcpy */
131     fputc ('$', fptr);
132     fputc (1, fptr);
133     fputc ((pkt_len_s16 + 16) >> 8, fptr);
134     fputc ((pkt_len_s16 + 16), fptr);
135 
136     fputc (comspec >> 8, fptr);
137     fputc (comspec, fptr);
138     fputc ((pkt_len_s16 + 16) >> 8, fptr);
139     fputc ((pkt_len_s16 + 16), fptr);
140     fputc (priority, fptr);
141     fputc (0, fptr);
142     fputc (comref >> 8, fptr);
143     fputc (comref, fptr);
144     fputc (data_len >> 24, fptr);
145     fputc (data_len >> 16, fptr);
146     fputc (data_len >> 8, fptr);
147     fputc (data_len, fptr);
148     fputc (0, fptr);
149     fputc (2, fptr);
150     fputc (0, fptr);
151     fputc (0, fptr);
152 
153     fwrite (data, pkt_len_s16, 1, fptr);
154 }
155 
156 
157 /*
158   SCP3 packet structure:
159 
160     Bytes  Description
161     --------------------------------------------
162       2    Command specifier
163       2    Packet length (N)
164       1    Priority
165       1    padding? (always zero)
166       2    Command reference number
167       4    Channel 0 buffer increment
168       4    version number? (always 01 04 00 00)
169      N-16  [remaining data]
170 
171     ComSpec  ComRef     Command
172     -------------------------------
173      0x186      1     Initialize1
174      0x18C     16     Initialize Printer name
175      0x1A1      1     Initialize4?
176      0x18f      2     Initialize2
177      0x183      1     Initialize3
178      0x181      1     Handle Media
179      0x180      1     Print Sweep
180 */
181 void
scp3_put(FILE * fptr,unsigned short comspec,unsigned short pkt_len_s16,unsigned char priority,unsigned short comref,unsigned data_len,void * data)182 scp3_put (FILE * fptr, unsigned short comspec,
183 	  unsigned short pkt_len_s16,
184 	  unsigned char priority, unsigned short comref,
185 	  unsigned data_len, void *data)
186 {
187     /* encapsulate the vlink_put call in here, to avoid a memcpy */
188     fputc ('$', fptr);
189     fputc (1, fptr);
190     fputc ((pkt_len_s16 + 16) >> 8, fptr);
191     fputc ((pkt_len_s16 + 16), fptr);
192 
193     fputc (comspec >> 8, fptr);
194     fputc (comspec, fptr);
195     fputc ((pkt_len_s16 + 16) >> 8, fptr);
196     fputc ((pkt_len_s16 + 16), fptr);
197     fputc (priority, fptr);
198     fputc (0, fptr);
199     fputc (comref >> 8, fptr);
200     fputc (comref, fptr);
201     fputc (data_len >> 24, fptr);
202     fputc (data_len >> 16, fptr);
203     fputc (data_len >> 8, fptr);
204     fputc (data_len, fptr);
205     fputc (1, fptr);
206     fputc (4, fptr);
207     fputc (0, fptr);
208     fputc (0, fptr);
209 
210     fwrite (data, pkt_len_s16, 1, fptr);
211 }
212 
213 
214 void
ppa_init_job(ppaPrinter_t * printer)215 ppa_init_job (ppaPrinter_t * printer)
216 {
217     unsigned char init1[8] =
218 
219 	{ 0x00, 0x00, 0x01, 0xf4, 0x01, 0x00, 0x00, 0x00 };
220     unsigned char init2[4] = { 0xde, 0xad, 0xbe, 0xef };
221     unsigned char init3[8] =
222 
223 	{ 0xde, 0xad, 0xbe, 0xef, 0x02, 0x00, 0x00, 0x00 };
224     unsigned char init4[60] = "!!TAZ            \x81*HP DeskJet 1000C Prin (Copy 2)*FILE!!\x00\x00\x00";	/* plus 0 terminator */
225     unsigned char init5[4] = { 0x01, 0x01, 0x00, 0x00 };
226 
227     switch (printer->version)
228     {
229     case HP820:
230 	scp_put (printer->fptr, 35, 1, 7, sizeof (init1), init1);
231 	vlink_put (printer->fptr, 0, sizeof (init2), init2);
232 	scp_put (printer->fptr, 101, 2, 7, sizeof (init3), init3);
233 	break;
234     case HP7X0:
235 	scp2_put (printer->fptr, 0x0186, sizeof (init1), 7, 1, 0, init1);
236 	vlink_put (printer->fptr, 0, sizeof (init2), init2);
237 	scp2_put (printer->fptr, 0x018f, sizeof (init3), 7, 2, 4, init3);
238 	break;
239     case HP1000:
240 	scp3_put (printer->fptr, 0x0186, sizeof (init1), 7, 16, 0, init1);
241 	scp3_put (printer->fptr, 0x018C, sizeof (init4), 7, 1, 0, init4);
242 	scp3_put (printer->fptr, 0x01A1, sizeof (init5), 7, 1, 0, init5);
243 	vlink_put (printer->fptr, 0, sizeof (init2), init2);
244 	scp3_put (printer->fptr, 0x018f, sizeof (init3), 7, 2, 4, init3);
245 	break;
246     default:
247       snprintf(syslog_message,message_size,"ppa_init_job(): %s",
248 		gMessages[E_PPA_UNKNOWN]);
249       wrap_syslog (LOG_CRIT,"%s",syslog_message);
250 
251     }
252 }
253 
254 void
ppa_end_print(ppaPrinter_t * printer)255 ppa_end_print (ppaPrinter_t * printer)
256 {
257     unsigned char pageA[4] = { 0x05, 0x01, 0x03, 0x84 };
258 
259     if (printer->version == HP1000)
260 	scp3_put (printer->fptr, 0x0181, sizeof (pageA), 7, 2, 0, pageA);
261 }
262 
263 void
ppa_init_page(ppaPrinter_t * printer)264 ppa_init_page (ppaPrinter_t * printer)
265 {
266     unsigned char pageA[16] =
267 	{ 0x28, 0x2d, 0x00, 0x41, 0x29, 0x2e, 0x00, 0x42,
268 	0x29, 0x2e, 0x00, 0x42, 0x29, 0x2e, 0x00, 0x42
269     };
270     unsigned char pageB[16] =
271 	{ 0x28, 0x2d, 0x00, 0x41, 0x2d, 0x32, 0x00, 0x46,
272 	0x2d, 0x32, 0x00, 0x46, 0x2d, 0x32, 0x00, 0x46
273     };
274 
275     switch (printer->version)
276       {
277       case HP820:
278 	scp_put (printer->fptr, 21, 1, 5, sizeof (pageA), pageA);
279 	break;
280       case HP7X0:
281 	scp2_put (printer->fptr, 0x0183, sizeof (pageB), 5, 1, 0, pageB);
282 	break;
283       case HP1000:
284 	scp3_put (printer->fptr, 0x0183, sizeof (pageA), 5, 1, 0, pageA);
285 	break;
286       default:
287       snprintf(syslog_message,message_size,"ppa_init_page(): %s",
288 		gMessages[E_PPA_UNKNOWN]);
289       wrap_syslog (LOG_CRIT,"%s",syslog_message);
290 
291       }
292 }
293 
294 void
ppa_load_page(ppaPrinter_t * printer)295 ppa_load_page (ppaPrinter_t * printer)
296 {
297     unsigned char loadA[4] = { 0x01, 0x01, 0x09, 0x60 };
298     unsigned char loadB[4] = { 0x01, 0x01, 0x12, 0xc0 };
299     unsigned char loadC[4] = { 0x01, 0x01, 0x07, 0x08 };
300 
301     switch (printer->version)
302     {
303     case HP820:
304 	scp_put (printer->fptr, 19, 1, 7, sizeof (loadA), loadA);
305 	break;
306     case HP7X0:
307 	scp2_put (printer->fptr, 0x0181, sizeof (loadB), 7, 1, 0, loadB);
308 	break;
309     case HP1000:
310 	scp3_put (printer->fptr, 0x0181, sizeof (loadC), 7, 1, 0, loadC);
311 	break;
312     default:
313       snprintf(syslog_message,message_size, "ppa_load_page(): %s",
314 		gMessages[E_PPA_UNKNOWN]);
315       wrap_syslog (LOG_CRIT,"%s",syslog_message);
316 
317     }
318 }
319 
320 void
ppa_eject_page(ppaPrinter_t * printer)321 ppa_eject_page (ppaPrinter_t * printer)
322 {
323     unsigned char loadA[4] = { 0x02, 0x01, 0x09, 0x60 };
324     unsigned char loadB[4] = { 0x02, 0x01, 0x12, 0xc0 };
325     unsigned char loadC[4] = { 0x02, 0x01, 0x07, 0x08 };
326 
327     switch (printer->version)
328     {
329     case HP820:
330 	scp_put (printer->fptr, 19, 1, 7, sizeof (loadA), loadA);
331 	break;
332     case HP7X0:
333 	scp2_put (printer->fptr, 0x0181, sizeof (loadB), 7, 1, 0, loadB);
334 	break;
335     case HP1000:
336 	scp3_put (printer->fptr, 0x0181, sizeof (loadC), 7, 1, 0, loadC);
337 	break;
338     default:
339       snprintf(syslog_message,message_size, "ppa_eject_page(): %s",
340 		gMessages[E_PPA_UNKNOWN]);
341       wrap_syslog (LOG_CRIT,"%s",syslog_message);
342      }
343 }
344 
345 int
compress(unsigned char * in,int num_lines_d2,int final_len,unsigned char * iout)346 compress (unsigned char *in, int num_lines_d2, int final_len,
347 	  unsigned char *iout)
348 {
349     unsigned char *out = iout;
350     int I, len = num_lines_d2;
351     unsigned compressed_len = 0;
352 
353 
354     /* abandon compression if datasize expands!  */
355 
356     for (I = 0; I < final_len; I += num_lines_d2, in += num_lines_d2)
357     {
358 	int i = 0;
359 
360 	while (i < len)
361 	{
362 	    /* Find the size of duplicate values */
363 	    int dup_len = 0;
364 
365 	    while ((i + dup_len < len) && (in[i + dup_len] == in[i]))
366 	    {
367 		dup_len++;
368 	    }
369 	    /* See if we have enough zeros to be worth compressing. */
370 	    /* I figure one is enough. */
371 	    if ((dup_len >= 1) && (in[i] == 0))
372 	    {
373 		/* Output run of zeros. */
374 		while (dup_len >= 128)
375 		{
376 		    /* Max is 128 */
377 		    *out++ = 0x00;
378 		    compressed_len++;
379 		    if (compressed_len > final_len)
380 		      return 0;
381 		    i += 128;
382 		    dup_len -= 128;
383 		}
384 		if (dup_len >= 1)
385 		{
386 		    *out++ = dup_len;
387 		    compressed_len++;
388 		    if (compressed_len > final_len)
389 		      return 0;
390 
391 		    i += dup_len;
392 		}
393 		/* See if we have enough non-zeros to be worth compressing. */
394 		/* Here two should be enough. */
395 	    }
396 	    else if (dup_len >= 2)
397 	    {
398 		/* Output run of duplicates. */
399 		while (dup_len >= 64)
400 		{
401 		    /* Max is 64 */
402 		    *out++ = (char) 0x80;
403 		    *out++ = (char) in[i];
404 		    compressed_len +=2;
405 		    if (compressed_len > final_len)
406 		      return 0;
407 
408 		    i += 64;
409 		    dup_len -= 64;
410 		}
411 		if (dup_len >= 2)
412 		{
413 		    *out++ = dup_len + 0x80;
414 		    *out++ = in[i];
415 		    compressed_len +=2;
416 		    if (compressed_len > final_len)
417 		      return 0;
418 
419 		    i += dup_len;
420 		}
421 	    }
422 	    else
423 	    {
424 		/* Look for two zeros, or three duplicates to end literal run. */
425 		/* Note this is one more than the number to start a run. */
426 		int lit_len = -1;
427 		int add_more = 1;
428 
429 		while (add_more)
430 		{
431 		    lit_len++;
432 		    if (i + lit_len == len)
433 			add_more = 0;
434 		    /* Always add more if we are near the very end. */
435 		    if (i + lit_len < len - 3)
436 		    {
437 			char a = in[i + lit_len + 0];
438 			char b = in[i + lit_len + 1];
439 			char c = in[i + lit_len + 2];
440 
441 			/* See if there are enough zeros */
442 			if ((a == b) && (b == 0))
443 			    add_more = 0;
444 			/* See if there are enough duplicates */
445 			if ((a == b) && (b == c))
446 			    add_more = 0;
447 		    }
448 		}
449 		/* Output run of literals. */
450 		while (lit_len >= 64)
451 		{
452 		    /* Max is 64 */
453 		    int j;
454 
455 		    *out++ = (char) 0xc0;
456 		    compressed_len ++;
457 		    for (j = i; j < i + 64; j++)
458 		    {
459 			*out++ = in[j];
460 		    }
461 		    compressed_len += 64;
462 		    if (compressed_len > final_len)
463 		      return 0;
464 		    i += 64;
465 		    lit_len -= 64;
466 		}
467 		if (lit_len)
468 		{
469 		    int j;
470 
471 		    *out++ = lit_len + 0xc0;
472 		    compressed_len ++;
473 		    for (j = i; j < i + lit_len; j++)
474 		    {
475 			*out++ = in[j];
476 		    }
477 		    compressed_len += lit_len;
478 		    if (compressed_len > final_len)
479 		      return 0;
480 		    i += lit_len;
481 		}
482 	    }
483 	}
484     }
485     if (compressed_len > final_len)
486       return 0;
487 
488     return out - iout;
489 }
490 
491 static inline void
packShort(int x,unsigned char * y)492 packShort (int x, unsigned char *y)
493 {
494     y[0] = x >> 8;
495     y[1] = x;
496 }
497 
498 static inline void
packLong(unsigned long x,unsigned char * y)499 packLong (unsigned long x, unsigned char *y)
500 {
501     packShort(x >> 16, y);
502     packShort(x, y + 2);
503 #if 0
504     unsigned short t;
505 
506     t = (unsigned short) ((x & 0xffff0000) >> 16);
507     packShort (t, y);
508     packShort ((unsigned short) x & 0xffff, y + 2);
509 #endif
510 }
511 
512 /*#define do_compress_data (1) */
513 
514 void
ppa_print_sweep(ppaPrinter_t * printer,ppaSweepData_t * data)515 ppa_print_sweep (ppaPrinter_t * printer, ppaSweepData_t * data)
516 {
517   unsigned char *pc, *tpc;
518   unsigned i, datasize = data->data_size;
519   unsigned char sweep_packet[144];
520   int sweep_packet_size;
521   unsigned short HP7X0constants[] = { 0x8ca0, 0x4650, 0x12c0 };
522   unsigned short HP820constants[] = { 0x4650, 0x1c20, 0x0960 };
523   unsigned short HP1000constants[] = { 0x4650, 0x2328, 0x0708 };
524   unsigned short *constants;
525   int nozzle_data_size;
526   int MF;			/* Multiplicative Factor -- quick hack */
527 
528   unsigned char do_compress_data;
529 
530   DPRINTF("ppa_print_sweep(): Dir: %d Color: %d Size: %d Vpos: %d Hpos: %d,%d\n",
531 	  data->direction, data->in_color, data->data_size, data->vertical_pos,
532 	  data->left_margin, data->right_margin );
533   assert( ((data->direction == left_to_right) || (data->direction == right_to_left)) );
534 
535   if (data->in_color && !gCompress )
536     do_compress_data = 0;
537   else
538     do_compress_data = 1;
539 
540 
541 
542   pc = data->image_data;
543 
544   DPRINTF(" ppa_print_sweep(): datasize= %d\n", datasize);
545 
546   if (do_compress_data) {
547     unsigned compressed_datasize;
548     if (!(pc = malloc ((datasize / 64 + 1) * 65)))
549       {
550 	snprintf(syslog_message,message_size, "ppa_print_sweep(): %s",
551 		 gMessages[E_PPA_BADMALLOC]);
552 	wrap_syslog (LOG_CRIT,"%s",syslog_message);
553 	  exit (-1);
554       }
555     compressed_datasize =
556       compress (data->image_data,
557 		data->nozzle_data->pins_used_d2, datasize, pc);
558     if (!compressed_datasize) {
559       /* compression would increase datsize ! */
560       free (pc);
561 	  do_compress_data = 0;
562 	  pc = data->image_data;
563     } else {
564       datasize = compressed_datasize;
565       DPRINTF(" ppa_print_sweep():compressed datasize= %d\n", datasize);
566     }
567 
568   }
569 
570   /* send image data 16k at a time */
571   for (i = 0, tpc = pc; i < datasize; tpc += 16384, i += 16384)
572     {
573       vlink_put (printer->fptr, 0, ((datasize - i) > 16384) ? 16384 : (datasize - i), tpc);
574     }
575 
576 
577   /* memory leak fix courtesy of John McKown */
578   if (do_compress_data && pc){
579     free (pc);
580     pc = NULL;
581   }
582 
583   /* construct sweep packet */
584   switch (printer->version) {
585   case HP820:
586     constants = HP820constants;
587     MF = 1;
588     break;
589   case HP7X0:
590     constants = HP7X0constants;
591 	    MF = 2;
592 	    break;
593   case HP1000:
594     constants = HP1000constants;
595     MF = 1;
596     break;
597   default:
598     snprintf(syslog_message,message_size, "ppa_print_sweep(): %s",
599 	     gMessages[E_PPA_UNKNOWN]);
600 	      wrap_syslog (LOG_CRIT,"%s",syslog_message);
601 	      return;
602   }
603 
604   sweep_packet[0] = 0;
605   sweep_packet[1] = do_compress_data;
606   sweep_packet[2] = data->direction == right_to_left ? 1 : 2;
607   sweep_packet[3] = data->in_color ? 14 : 1;
608 
609   packLong (datasize, sweep_packet + 4);
610 
611   memset (sweep_packet + 8, 0, 8);
612 
613   if (data->in_color)
614     packLong (MF * (data->vertical_pos +
615 		    /*96+ */ printer->y_offset) /*+ 1*/,
616 	      sweep_packet + 16);
617   else
618     packLong (MF *
619 	      (data->vertical_pos +
620 	       printer->y_offset), sweep_packet + 16);
621   packShort (constants[0], sweep_packet + 20);
622   packShort (MF *
623 	     (data->left_margin + printer->x_offset) /*+ 1*/,
624 	     sweep_packet + 22);
625   packShort (MF *
626 	     (data->right_margin + printer->x_offset) /*+ 1*/,
627 	     sweep_packet + 24);
628   if (data->in_color)
629     packShort (0x2ee0, sweep_packet + 26);
630   else
631     packShort (constants[1], sweep_packet + 26);	/* 2ee0 in color on 820 */
632   packShort (constants[2], sweep_packet + 28);
633   packShort (0x100, sweep_packet + 30);
634 
635 
636   if (data->next) {
637     sweep_packet[32] =
638       data->next->direction == right_to_left ? 1 : 2;
639     sweep_packet[33] = data->next->in_color ? 14 : 1;
640     packLong (MF *
641 	      (data->next->vertical_pos +
642 	       printer->y_offset), sweep_packet + 34);
643     packShort (MF *
644 	       (data->next->left_margin +
645 		printer->x_offset), sweep_packet + 38);
646     packShort (MF *
647 	       (data->next->right_margin +
648 		printer->x_offset), sweep_packet + 40);
649     if (data->in_color)
650       packShort (0x2ee0, sweep_packet + 42);
651     else
652       packShort (constants[1], sweep_packet + 42);	/* 2ee0 in color on 820 */
653 		packShort (constants[2], sweep_packet + 44);
654   }
655   else
656     memset (sweep_packet + 32, 0, 14);
657   sweep_packet[46] = 8;
658 
659   nozzle_data_size = data->nozzle_data_size;
660   if (nozzle_data_size > 6) {
661     snprintf(syslog_message,message_size, "ppa_print_sweep(): %s %d\n",
662 	     gMessages[W_PPA_NOZZLE], nozzle_data_size);
663     wrap_syslog (LOG_WARNING,"%s",syslog_message);
664 
665     nozzle_data_size = 6;
666   }
667   sweep_packet[47] = nozzle_data_size;
668 
669   for (pc = sweep_packet + 48, i = 0;
670        i < nozzle_data_size; i++, pc += 16) {
671     packShort (data->nozzle_data[i].DPI, pc);
672     packShort (data->nozzle_data[i].pins_used_d2, pc + 2);
673     packShort (data->nozzle_data[i].unused_pins_p1, pc + 4);
674     packShort (data->nozzle_data[i].first_pin, pc + 6);
675     packShort (data->nozzle_data[i].pins_used_d2, pc + 8);
676     packShort (MF * (data->nozzle_data[i].left_margin + printer->x_offset),
677 	       pc + 10);
678     packShort (MF * (data->nozzle_data[i].right_margin + printer->x_offset),
679 	       pc + 12);
680     pc[14] = data->nozzle_data[i].nozzle_delay;
681     pc[15] = 0;
682   }
683 
684   sweep_packet_size = data->in_color ? 144 : 80;
685 
686 
687   /* send sweep packet */
688   switch (printer->version) {
689   case HP820:
690     scp_put (printer->fptr, 18, 1, 7, sweep_packet_size, sweep_packet);
691     break;
692   case HP7X0:
693     scp2_put (printer->fptr, 0x0180, sweep_packet_size,
694 		      7, 1, datasize, sweep_packet);
695     break;
696   case HP1000:
697     scp3_put (printer->fptr, 0x0180, sweep_packet_size,
698 	      7, 1, datasize, sweep_packet);
699     break;
700   default:
701     snprintf(syslog_message,message_size,"ppa_print_sweep(): %s",
702 	     gMessages[E_PPA_UNKNOWN]);
703     wrap_syslog (LOG_CRIT,"%s",syslog_message);
704 
705     return;
706   }
707 }
708 
709 
710 
711 void
ppa_print_sweeps(ppaPrinter_t * printer,ppaSweepData_t * data)712 ppa_print_sweeps (ppaPrinter_t * printer, ppaSweepData_t * data)
713 {
714     ppaSweepData_t *current_sweep;
715 
716     for (current_sweep = data; current_sweep;
717 	 current_sweep = current_sweep->next)
718 	ppa_print_sweep (printer, current_sweep);
719 }
720