1 /*
2  * Hewlett-Packard Co. Inkjet Driver
3  * Copyright (c) 2001, Hewlett-Packard Co.
4  *
5  * This ghostscript printer driver is the glue code for using the
6  * HP Inkjet Server (hpijs).
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 
23 /* $Id: gdevhpij.c,v 1.3.2.1 2002/04/10 09:33:25 giles Exp $ */
24 
25 #include "gdevprn.h"
26 #include "gdevpcl.h"
27 #include "gxdevice.h"
28 #include <sys/stat.h>
29 #include <sys/shm.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <syslog.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <limits.h>
36 #include "gdevhpij.h"
37 
38 
39 /* Structure for hpijs device. */
40 typedef struct gx_device_hpijs_s
41 {
42    gx_device_common;
43    gx_prn_device_common;
44    /* Additional parameters for hpijs */
45    int PrintMode;		/* qrayscale=0, normal=1, photo=2, ??? */
46    SRVD sd;			/* server descriptor */
47    gs_param_string DeviceName;
48 } gx_device_hpijs;
49 
50 /* Default X and Y resolution. */
51 #ifndef X_DPI
52 #  define X_DPI 300
53 #endif
54 #ifndef Y_DPI
55 #  define Y_DPI 300
56 #endif
57 
58 /* Margins are left, bottom, right, top. */
59 #define DESKJET_MARGINS_LETTER   0.25, 0.44, -0.25, 0.167
60 #define DESKJET_MARGINS_A4       0.125, 0.44, -0.125, 0.167
61 //#define DESKJET_MARGINS_LETTER   0.25, 0.44, 0, 0.167
62 //#define DESKJET_MARGINS_A4       0.125, 0.44, 0, 0.167
63 
64 private int hpijs_print_page(gx_device_printer * pdev, FILE * prn_stream, const char *dname);
65 
66 private dev_proc_open_device(hpijs_open);
67 private dev_proc_close_device(hpijs_close);
68 private dev_proc_print_page(dj630_print_page);
69 private dev_proc_print_page(dj6xx_print_page);
70 private dev_proc_print_page(dj6xx_photo_print_page);
71 private dev_proc_print_page(dj8xx_print_page);
72 private dev_proc_print_page(dj9xx_print_page);
73 private dev_proc_print_page(dj9xx_vip_print_page);
74 private dev_proc_print_page(ap21xx_print_page);
75 private dev_proc_print_page(hpijs_ext_print_page);
76 private dev_proc_get_params(hpijs_get_params);
77 private dev_proc_put_params(hpijs_put_params);
78 
79 private gx_device_procs prn_hpijs_procs =
80 prn_color_params_procs(hpijs_open, gdev_prn_output_page, hpijs_close,
81 		       gx_default_rgb_map_rgb_color,
82 		       gx_default_rgb_map_color_rgb, hpijs_get_params,
83 		       hpijs_put_params);
84 
85 gx_device_hpijs gs_DJ630_device =
86     { prn_device_std_body(gx_device_hpijs, prn_hpijs_procs, "DJ630",
87 			  DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
88 			  X_DPI, Y_DPI,
89 			  0, 0, 0, 0,	/* margins (lm,bm,rm,tm)  */
90 			  24, dj630_print_page),
91    2				/* PrintMode default */
92 };
93 
94 gx_device_hpijs gs_DJ6xx_device =
95     { prn_device_std_body(gx_device_hpijs, prn_hpijs_procs, "DJ6xx",
96 			  DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
97 			  X_DPI, Y_DPI,
98 			  0, 0, 0, 0,	/* margins (lm,bm,rm,tm)  */
99 			  24, dj6xx_print_page),
100    1				/* PrintMode default */
101 };
102 
103 gx_device_hpijs gs_DJ6xxP_device =
104     { prn_device_std_body(gx_device_hpijs, prn_hpijs_procs, "DJ6xxP",
105 			  DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
106 			  X_DPI, Y_DPI,
107 			  0, 0, 0, 0,	/* margins (lm,bm,rm,tm)  */
108 			  24, dj6xx_photo_print_page),
109    1				/* PrintMode default */
110 };
111 
112 gx_device_hpijs gs_DJ8xx_device =
113     { prn_device_std_body(gx_device_hpijs, prn_hpijs_procs, "DJ8xx",
114 			  DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
115 			  X_DPI, Y_DPI,
116 			  0, 0, 0, 0,	/* margins (lm,bm,rm,tm)  */
117 			  24, dj8xx_print_page),
118    1				/* PrintMode default */
119 };
120 
121 gx_device_hpijs gs_DJ9xx_device =
122     { prn_device_std_body(gx_device_hpijs, prn_hpijs_procs, "DJ9xx",
123 			  DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
124 			  X_DPI, Y_DPI,
125 			  0, 0, 0, 0,	/* margins (lm,bm,rm,tm)  */
126 			  24, dj9xx_print_page),
127    1				/* PrintMode default */
128 };
129 
130 gx_device_hpijs gs_DJ9xxVIP_device =
131     { prn_device_std_body(gx_device_hpijs, prn_hpijs_procs, "DJ9xxVIP",
132 			  DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
133 			  X_DPI, Y_DPI,
134 			  0, 0, 0, 0,	/* margins (lm,bm,rm,tm)  */
135 			  24, dj9xx_vip_print_page),
136    1				/* PrintMode default */
137 };
138 
139 gx_device_hpijs gs_AP21xx_device =
140     { prn_device_std_body(gx_device_hpijs, prn_hpijs_procs, "AP21xx",
141 			  DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
142 			  X_DPI, Y_DPI,
143 			  0, 0, 0, 0,	/* margins (lm,bm,rm,tm)  */
144 			  24, ap21xx_print_page),
145    2				/* PrintMode default */
146 };
147 
148 gx_device_hpijs gs_hpijs_device =
149     { prn_device_std_body(gx_device_hpijs, prn_hpijs_procs, "hpijs",
150 			  DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
151 			  X_DPI, Y_DPI,
152 			  0, 0, 0, 0,	/* margins (lm,bm,rm,tm)  */
153 			  24, hpijs_ext_print_page),
154    1				/* PrintMode default */
155 };
156 
157 static char s2c[80];
158 static char c2s[80];
159 
bug(const char * fmt,...)160 private int bug(const char *fmt, ...)
161 {
162    char buf[256];
163    va_list args;
164    int n;
165 
166    va_start(args, fmt);
167 
168    if ((n = vsnprintf(buf, 256, fmt, args)) == -1)
169       buf[255] = 0;		/* output was truncated */
170 
171    fprintf(stderr, buf);
172    syslog(LOG_WARNING, buf);
173 
174    fflush(stderr);
175    va_end(args);
176    return n;
177 }
178 
179 /* Get packet from the server. */
hpijs_get_pk(PK * pk,int fd)180 private int hpijs_get_pk(PK * pk, int fd)
181 {
182    return read(fd, pk, PIPE_BUF - 1);
183 }
184 
185 /* Write packet to the server. */
hpijs_put_pk(PK * pk,int fd)186 private int hpijs_put_pk(PK * pk, int fd)
187 {
188    return write(fd, pk, sizeof(PK));
189 }
190 
191 /* Write single command packet to server. */
hpijs_put_cmd(SRVD * sd,int cmd)192 private int hpijs_put_cmd(SRVD * sd, int cmd)
193 {
194    PK pk;
195 
196    pk.cmd = cmd;
197    if (hpijs_put_pk(&pk, sd->fdc2s) < 0)
198    {
199       bug("unable to write fifo %d: %m\n", sd->client_to_srv);
200       return -1;
201    }
202    if (hpijs_get_pk(&pk, sd->fds2c) < 0)	/* ack */
203    {
204       bug("unable to read fifo %d: %m\n", sd->client_to_srv);
205       return -1;
206    }
207 
208    return 0;
209 }
210 
211 /* Init server discriptor. */
hpijs_init_sd(SRVD * sd)212 private int hpijs_init_sd(SRVD * sd)
213 {
214    sd->fds2c = -1;
215    sd->fdc2s = -1;
216    sd->shmid = -1;
217    sd->shmbuf = NULL;
218    sd->srv_to_client = NULL;
219    sd->client_to_srv = NULL;
220    return 0;
221 }
222 
223 /* Close the server. */
hpijs_close_srv(SRVD * sd)224 private int hpijs_close_srv(SRVD * sd)
225 {
226    PK pk;
227 
228    if (sd->fdc2s >= 0)
229    {
230       /* Kill the server. */
231       pk.cmd = KILL;
232       hpijs_put_pk(&pk, sd->fdc2s);
233    }
234    if (sd->shmbuf != NULL)
235    {
236       /* Detach and release shared memory. */
237       shmdt(sd->shmbuf);
238       shmctl(sd->shmid, IPC_RMID, 0);
239    }
240    close(sd->fds2c);
241    close(sd->fdc2s);
242 
243    remove(sd->srv_to_client);
244    remove(sd->client_to_srv);
245    return 0;
246 }
247 
248 /* Spawn the server as a coprocess. */
hpijs_open_srv(SRVD * sd,FILE * prn_stream,int raster_width)249 private int hpijs_open_srv(SRVD * sd, FILE * prn_stream, int raster_width)
250 {
251    PK pk;
252    int fd;
253    mode_t mode = 0666;
254    int pid;
255 
256    /* Make sure we can find the server. */
257    //   if (access(SRVPATH, F_OK) < 0)
258    //   {
259    //      bug("unable to locate %s: %m\n", SRVPATH);
260    //      return -1;
261    //   }
262 
263    /* Assign fifo names for environment space, names must be const char. */
264    sprintf(s2c, "SRV_TO_CLIENT=/tmp/hpijs_s2c_%d", getpid());
265    sprintf(c2s, "CLIENT_TO_SRV=/tmp/hpijs_c2s_%d", getpid());
266 
267    /* Put fifo names in envirmoment space for child process. */
268    putenv(s2c);
269    putenv(c2s);
270 
271    /* Get local copy. */
272    sd->srv_to_client = getenv("SRV_TO_CLIENT");
273    sd->client_to_srv = getenv("CLIENT_TO_SRV");
274 
275    /* Create actual fifos in filesystem. */
276    if ((mkfifo(sd->srv_to_client, mode)) < 0)
277    {
278       bug("unable to create fifo %s: %m\n", sd->srv_to_client);
279       return -1;
280    }
281    if ((mkfifo(sd->client_to_srv, mode)) < 0)
282    {
283       bug("unable to create fifo %s: %m\n", sd->client_to_srv);
284       goto BUGOUT;
285    }
286 
287    /* Create shared memory for raster data. */
288    if ((sd->shmid = shmget(IPC_PRIVATE, raster_width, mode)) < 0)
289    {
290       bug("unable to create shared memory: %m\n");
291       goto BUGOUT;
292    }
293 
294    /* Spawn the server. */
295    if ((pid = fork()) < 0)
296    {
297       bug("unable to fork server: %m\n");
298       goto BUGOUT;
299    } else if (pid > 0)
300    {				/* parent */
301 
302       /* Open fifos. */
303       if ((sd->fds2c = open(sd->srv_to_client, O_RDONLY)) < 0)
304       {
305 	 bug("unable to open fifo %d: %m\n", sd->srv_to_client);
306 	 goto BUGOUT;
307       }
308       if ((sd->fdc2s = open(sd->client_to_srv, O_WRONLY)) < 0)
309       {
310 	 bug("unable to open fifo %d: %m\n", sd->client_to_srv);
311 	 goto BUGOUT;
312       }
313 
314       /* Attach to shared memory. */
315       if ((sd->shmbuf = shmat(sd->shmid, 0, 0)) < (char *) 0)
316       {
317 	 bug("unable to attach shared memory: %m\n");
318 	 goto BUGOUT;
319       }
320 
321       /* Send shmid to server. */
322       pk.shm.cmd = SET_SHMID;
323       pk.shm.id = sd->shmid;
324       hpijs_put_pk(&pk, sd->fdc2s);
325       hpijs_get_pk(&pk, sd->fds2c);
326 
327       return 0;
328 
329     BUGOUT:
330       hpijs_close_srv(sd);
331       return -1;
332 
333    } else
334    {				/* child */
335       /* Redirect print_stream to stdout. */
336       fd = fileno(prn_stream);
337       if (fd != STDOUT_FILENO)
338       {
339 	 if (dup2(fd, STDOUT_FILENO) != STDOUT_FILENO)
340 	    bug("unable redirect stdout: %m\n");
341       }
342       if (execlp(SRVPATH, SNAME, (char *) 0) < 0)
343       {
344 	 bug("unable to exec %s: %m\n", SRVPATH);
345 	 goto BUGOUT2;
346       }
347       exit(0);
348 
349     BUGOUT2:
350       exit(EXIT_FAILURE);
351    }
352 
353    return -1;
354 }
355 
hpijs_spawn_srv(gx_device_hpijs * pdev,FILE * prn_stream,const char * dname)356 private int hpijs_spawn_srv(gx_device_hpijs *pdev, FILE * prn_stream,
357 			    const char *dname)
358 {
359    PK pk;
360 
361    hpijs_init_sd(&pdev->sd);
362    if (hpijs_open_srv(&pdev->sd, prn_stream, pdev->width * 3) < 0)
363    {
364       bug("unable to spawn server\n");
365       return -1;
366    }
367 
368    pk.dev.cmd = SET_DEVICE_NAME;
369    strcpy(pk.dev.name, dname);
370    hpijs_put_pk(&pk, pdev->sd.fdc2s);
371    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
372 
373    pk.mode.cmd = SET_PRINTMODE;
374    pk.mode.val = pdev->PrintMode;
375    hpijs_put_pk(&pk, pdev->sd.fdc2s);
376    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
377 
378    pk.paper.cmd = SET_PAPER;
379    pk.paper.size = gdev_pcl_paper_size((gx_device *)pdev);
380    hpijs_put_pk(&pk, pdev->sd.fdc2s);
381    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
382 
383    pk.res.cmd = SET_RESOLUTION;
384    pk.res.x = pdev->x_pixels_per_inch;
385    pk.res.y = pdev->y_pixels_per_inch;
386    hpijs_put_pk(&pk, pdev->sd.fdc2s);
387    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
388 
389    pk.ppr.cmd = SET_PIXELS_PER_ROW;
390    pk.ppr.width = pdev->width;
391    pk.ppr.outwidth = pdev->width;      /* no simple pixel replication (scaling) */
392    hpijs_put_pk(&pk, pdev->sd.fdc2s);
393    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
394 
395 #ifdef zero_and_no_warning
396 /* API Test code. */
397    pk.ppr.cmd = GET_PRINTMODE;
398    hpijs_put_pk(&pk, pdev->sd.fdc2s);
399    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
400    bug("printmode=%d\n", pk.mode.val);
401 
402    pk.ppr.cmd = GET_PRINTMODE_CNT;
403    hpijs_put_pk(&pk, pdev->sd.fdc2s);
404    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
405    bug("number of printmodes=%d\n", pk.mode.val);
406 
407    pk.ppr.cmd = GET_PAPER;
408    hpijs_put_pk(&pk, pdev->sd.fdc2s);
409    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
410    bug("paper size=%d\n", pk.paper.size);
411 
412    pk.ppr.cmd = GET_EFFECTIVE_RESOLUTION;
413    hpijs_put_pk(&pk, pdev->sd.fdc2s);
414    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
415    bug("eff resolution x=%d, y=%d\n", pk.res.x, pk.res.y);
416 
417    pk.ppr.cmd = GET_PIXELS_PER_ROW;
418    hpijs_put_pk(&pk, pdev->sd.fdc2s);
419    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
420    bug("input width=%d, outwidth=%d\n", pk.ppr.width, pk.ppr.outwidth);
421 
422    pk.ppr.cmd = GET_SRV_VERSION;
423    hpijs_put_pk(&pk, pdev->sd.fdc2s);
424    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
425    bug("hpijs server %s\n", pk.ver.str);
426 
427    pk.ppr.cmd = GET_PRINTABLE_AREA;
428    hpijs_put_pk(&pk, pdev->sd.fdc2s);
429    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
430    bug("printable width=%.2f, height=%.2f (inches)\n", pk.parea.width, pk.parea.height);
431 
432    pk.ppr.cmd = GET_PHYSICAL_PAGE_SIZE;
433    hpijs_put_pk(&pk, pdev->sd.fdc2s);
434    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
435    bug("physical page size x=%.2f, y=%.2f (inches)\n", pk.psize.x, pk.psize.y);
436 
437    pk.ppr.cmd = GET_PRINTABLE_START;
438    hpijs_put_pk(&pk, pdev->sd.fdc2s);
439    hpijs_get_pk(&pk, pdev->sd.fds2c);	/* ack */
440    bug("printable start x=%.2f, y=%.2f (inches)\n", pk.pstart.x, pk.pstart.y);
441 /* End API test code. */
442 #endif
443 
444    return 0;
445 }
446 
hpijs_get_params(gx_device * pdev,gs_param_list * plist)447 private int hpijs_get_params(gx_device * pdev, gs_param_list * plist)
448 {
449    int code = gdev_prn_get_params(pdev, plist);
450    int ecode;
451 
452    if (code < 0)
453       return code;
454 
455    if ((ecode = param_write_int(plist, "PrintMode",
456 			&((gx_device_hpijs *)pdev)->PrintMode)) < 0)
457       code = ecode;
458 
459    if ((ecode = param_write_string(plist, "DeviceName", &((gx_device_hpijs *)pdev)->DeviceName)) < 0)
460      code = ecode;
461 
462    return code;
463 }
464 
hpijs_put_params(gx_device * pdev,gs_param_list * plist)465 private int hpijs_put_params(gx_device * pdev, gs_param_list * plist)
466 {
467    int ecode = 0;
468    int code;
469    gs_param_name param_name;
470    int pm = ((gx_device_hpijs *)pdev)->PrintMode;
471    gs_param_string dname = ((gx_device_hpijs *)pdev)->DeviceName;
472 
473    switch (code = param_read_int(plist, (param_name = "PrintMode"), &pm))
474    {
475    case 0:
476       if (pm < 0 || pm > 6)
477 	 ecode = gs_error_limitcheck;
478       else
479 	 break;
480       goto jqe;
481    default:
482       ecode = code;
483     jqe:param_signal_error(plist, param_name, ecode);
484    case 1:
485       break;
486    }
487 
488    if ((code = param_read_string(plist, (param_name = "DeviceName"), &dname)) < 0)
489      ecode = code;
490 
491    if (ecode < 0)
492       return ecode;
493    code = gdev_prn_put_params(pdev, plist);
494    if (code < 0)
495       return code;
496 
497    ((gx_device_hpijs *)pdev)->PrintMode = pm;
498    ((gx_device_hpijs *)pdev)->DeviceName = dname;
499    return 0;
500 }
501 
hpijs_open(gx_device * pdev)502 private int hpijs_open(gx_device * pdev)
503 {
504    static const float dj_a4[4] = { DESKJET_MARGINS_A4 };
505    static const float dj_letter[4] = { DESKJET_MARGINS_LETTER };
506    const float *m = NULL;
507 
508    /* Make sure width does not exceed 8". */
509    if (pdev->width > (pdev->x_pixels_per_inch * 8))
510       gx_device_set_width_height(pdev, pdev->x_pixels_per_inch * 8,
511 				 pdev->height);
512 
513    m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? dj_a4 : dj_letter);
514    gx_device_set_margins(pdev, m, true);
515 
516    return gdev_prn_open(pdev);
517 }
518 
hpijs_close(gx_device * pdev)519 private int hpijs_close(gx_device * pdev)
520 {
521    hpijs_close_srv(&((gx_device_hpijs *) pdev)->sd);
522    return gdev_prn_close(pdev);
523 }
524 
white(unsigned char * data,int size)525 private int white(unsigned char *data, int size)
526 {
527    int clean = 1;
528    int i;
529    for (i = 0; i < size; i++)
530       if (data[i] != 0xFF)
531       {
532 	 clean = 0;
533 	 break;
534       }
535    return clean;
536 }
537 
dj630_print_page(gx_device_printer * pdev,FILE * prn_stream)538 private int dj630_print_page(gx_device_printer * pdev, FILE * prn_stream)
539 {
540    return hpijs_print_page(pdev, prn_stream, "DJ630");
541 }
542 
dj6xx_print_page(gx_device_printer * pdev,FILE * prn_stream)543 private int dj6xx_print_page(gx_device_printer * pdev, FILE * prn_stream)
544 {
545    return hpijs_print_page(pdev, prn_stream, "DJ6xx");
546 }
547 
dj6xx_photo_print_page(gx_device_printer * pdev,FILE * prn_stream)548 private int dj6xx_photo_print_page(gx_device_printer * pdev,
549 				   FILE * prn_stream)
550 {
551    return hpijs_print_page(pdev, prn_stream, "DJ6xxPhoto");
552 }
553 
dj8xx_print_page(gx_device_printer * pdev,FILE * prn_stream)554 private int dj8xx_print_page(gx_device_printer * pdev, FILE * prn_stream)
555 {
556    return hpijs_print_page(pdev, prn_stream, "DJ8xx");
557 }
558 
dj9xx_print_page(gx_device_printer * pdev,FILE * prn_stream)559 private int dj9xx_print_page(gx_device_printer * pdev, FILE * prn_stream)
560 {
561    return hpijs_print_page(pdev, prn_stream, "DJ9xx");
562 }
563 
dj9xx_vip_print_page(gx_device_printer * pdev,FILE * prn_stream)564 private int dj9xx_vip_print_page(gx_device_printer * pdev,
565 				 FILE * prn_stream)
566 {
567    return hpijs_print_page(pdev, prn_stream, "DJ9xxVIP");
568 }
569 
ap21xx_print_page(gx_device_printer * pdev,FILE * prn_stream)570 private int ap21xx_print_page(gx_device_printer * pdev, FILE * prn_stream)
571 {
572    return hpijs_print_page(pdev, prn_stream, "AP21xx");
573 }
574 
hpijs_ext_print_page(gx_device_printer * pdev,FILE * prn_stream)575 private int hpijs_ext_print_page(gx_device_printer * pdev, FILE * prn_stream)
576 {
577    char name[DEVICE_NAME_MAX];
578    int len;
579 
580    len = ((gx_device_hpijs *)pdev)->DeviceName.size;
581    if ((len == 0) || (len >= DEVICE_NAME_MAX))
582       return gs_note_error(gs_error_invalidaccess);
583 
584    strncpy(name, ((gx_device_hpijs *)pdev)->DeviceName.data, len);
585    name[len]=0;
586    return hpijs_print_page(pdev, prn_stream, name);
587 }
588 
589 /* Send the page to the printer. */
hpijs_print_page(gx_device_printer * pdev,FILE * prn_stream,const char * dname)590 private int hpijs_print_page(gx_device_printer * pdev, FILE * prn_stream, const char *dname)
591 {
592    int line_size;
593    int last_row;
594    int lnum, code = 0;
595    int isnew;
596 
597    isnew = gdev_prn_file_is_new(pdev);
598 
599    if (isnew)
600    {
601       if (hpijs_spawn_srv((gx_device_hpijs *)pdev, prn_stream, dname) != 0)
602 	 return gs_note_error(gs_error_invalidaccess);
603    }
604 
605    line_size = gx_device_raster((gx_device *)pdev, 0);
606    last_row = dev_print_scan_lines(pdev);
607 
608    for (lnum = 0; lnum < last_row; lnum++)
609    {
610       code = gdev_prn_copy_scan_lines(pdev, lnum,
611 				   ((gx_device_hpijs *) pdev)->sd.shmbuf,
612 				   line_size);
613       if (code < 0)
614 	 return -1;
615       if (!white(((gx_device_hpijs *)pdev)->sd.shmbuf, line_size))
616       {
617 	if (hpijs_put_cmd(&((gx_device_hpijs *)pdev)->sd, SND_RASTER) == -1)
618 	  return -1;
619       } else
620       {
621 	  if (hpijs_put_cmd (&((gx_device_hpijs *)pdev)->sd, SND_NULL_RASTER) == -1)
622 	    return -1;
623       }
624    }
625 
626    hpijs_put_cmd(&((gx_device_hpijs *)pdev)->sd, NEW_PAGE);
627 
628    return code;
629 }
630