1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 /* Sony NWP-533 driver for GhostScript */
17 #include "gdevprn.h"
18 #define prn_dev ((gx_device_printer *)dev) /* needed in 5.31 et seq */
19 #include <sys/ioctl.h>
20 #include <newsiop/lbp.h>
21 
22 /***
23  *** Note: this driver was contributed by a user, Tero Kivinen:
24  ***       please contact kivinen@joker.cs.hut.fi if you have questions.
25  ***/
26 
27 #define A4_PAPER 1
28 
29 #ifdef A4_PAPER
30 #define PAPER_XDOTS A4_XDOTS
31 #define PAPER_YDOTS A4_YDOTS
32 #else
33 #define PAPER_XDOTS B4_XDOTS
34 #define PAPER_YDOTS B4_YDOTS
35 #endif
36 
37 #ifndef TRUE
38 #define TRUE 1
39 #endif
40 #ifndef FALSE
41 #define FALSE 0
42 #endif
43 
44 /* The device descriptor */
45 static dev_proc_open_device(nwp533_open);
46 static dev_proc_print_page(nwp533_print_page);
47 static dev_proc_close_device(nwp533_close);
48 /* Since the print_page doesn't alter the device, this device can print in the background */
49 static gx_device_procs nwp533_procs =
50   prn_procs(nwp533_open, gdev_prn_bg_output_page_seekable, nwp533_close);
51 
52 const gx_device_printer far_data gs_nwp533_device =
53   prn_device(nwp533_procs, "nwp533",
54         PAPER_XDOTS * 10.0 / DPI,	/* width_10ths */
55         PAPER_YDOTS * 10.0 / DPI,	/* height_10ths */
56         DPI,				/* x_dpi */
57         DPI,				/* y_dpi */
58         0,0,0,0,			/* margins */
59         1, nwp533_print_page);
60 
61 /* return True if should retry - False if should quit */
62 static int
analyze_error(int printer_file)63 analyze_error(int printer_file)
64 {
65   struct lbp_stat status;
66   char *detail = NULL, *old_detail = NULL;
67   int waiting = TRUE;
68   int retry_after_return = TRUE;
69 
70   if(ioctl(printer_file, LBIOCRESET, 0) < 0)
71     {
72       perror("ioctl(LBIOCRESET)");
73       return FALSE;
74     }
75   if (ioctl(printer_file, LBIOCSTATUS, &status) < 0)
76     {
77       perror("ioctl(LBIOCSTATUS)");
78       return FALSE;
79     }
80 
81   do
82     {
83       /* Is there an error */
84       if(status.stat[0] & (ST0_CALL | ST0_REPRINT_REQ | ST0_WAIT | ST0_PAUSE))
85         {
86           if(status.stat[1] & ST1_NO_CARTRIGE)/* mispelled? */
87             detail = "No cartridge - waiting";
88           else if(status.stat[1] & ST1_NO_PAPER)
89             detail = "Out of paper - waiting";
90           else if(status.stat[1] & ST1_JAM)
91             detail = "Paper jam - waiting";
92           else if(status.stat[1] & ST1_OPEN)
93             detail = "Door open - waiting";
94           else if(status.stat[1] & ST1_TEST)
95             detail = "Test printing - waiting";
96           else {
97             waiting = FALSE;
98             retry_after_return = FALSE;
99 
100             if(status.stat[2] & ST2_FIXER)
101               detail = "Fixer trouble - quiting";
102             else if(status.stat[2] & ST2_SCANNER)
103               detail = "Scanner trouble - quiting";
104             else if(status.stat[2] & ST2_MOTOR)
105               detail = "Scanner motor trouble - quiting";
106             else if(status.stat[5] & ST5_NO_TONER)
107               detail = "No toner - quiting";
108           }
109         }
110       else
111         {
112           waiting = FALSE;
113         }
114       if(detail != NULL && detail != old_detail)
115         {
116           perror(detail);
117           old_detail = detail;
118         }
119       if(waiting)
120         {
121           ioctl(1, LBIOCRESET, 0);
122           sleep(5);
123           ioctl(1, LBIOCSTATUS, &status);
124         }
125     }
126   while(waiting);
127   return retry_after_return;
128 }
129 
130 static int
nwp533_open(gx_device * dev)131 nwp533_open(gx_device *dev)
132 {
133   gx_device_printer *pdev = (gx_device_printer *) dev;
134 
135   if (pdev->fname[0] == '\0')
136     {
137       strcpy(pdev->fname, "/dev/lbp");
138     }
139   return gdev_prn_open(dev);
140 }
141 
142 static int
nwp533_close(gx_device * dev)143 nwp533_close(gx_device *dev)
144 {
145   if (((gx_device_printer *) dev)->file != NULL)
146     {
147       int printer_file;
148 
149       printer_file = fileno(((gx_device_printer *) dev)->file);
150     restart2:
151       if(ioctl(printer_file, LBIOCSTOP, 0) < 0)
152         {
153           if(analyze_error(printer_file))
154             goto restart2;
155           perror("Waiting for device");
156           return_error(gs_error_ioerror);
157         }
158     }
159   return gdev_prn_close(dev);
160 }
161 
162 /* Send the page to the printer. */
163 static int
nwp533_print_page(gx_device_printer * dev,gp_file * prn_stream)164 nwp533_print_page(gx_device_printer *dev, gp_file *prn_stream)
165 {
166   int lnum, code = 0;
167   int line_size = gdev_mem_bytes_per_scan_line(dev);
168   byte *in;
169   int printer_file;
170   printer_file = fileno(prn_stream);
171 
172   if (line_size % 4 != 0)
173     {
174       line_size += 4 - (line_size % 4);
175     }
176   in = (byte *) gs_malloc(dev->memory, line_size, 1, "nwp533_output_page(in)");
177   if (in == NULL)
178       return_error(gs_error_VMerror);
179  restart:
180   if(ioctl(printer_file, LBIOCSTOP, 0) < 0)
181     {
182       if(analyze_error(printer_file))
183         goto restart;
184       perror("Waiting for device");
185       return_error(gs_error_ioerror);
186     }
187   lseek(printer_file, 0, 0);
188 
189   for ( lnum = 0; lnum < dev->height; lnum++)
190     {
191       code = gdev_prn_copy_scan_lines(prn_dev, lnum, in, line_size);
192       if (code < 0)
193           goto xit;
194       if(write(printer_file, in, line_size) != line_size)
195         {
196           perror("Writting to output");
197           return_error(gs_error_ioerror);
198         }
199     }
200  retry:
201   if(ioctl(printer_file, LBIOCSTART, 0) < 0)
202     {
203       if(analyze_error(printer_file))
204         goto retry;
205       perror("Starting print");
206       return_error(gs_error_ioerror);
207     }
208 xit:
209   gs_free(dev->memory, in, line_size, 1, "nwp533_output_page(in)");
210 
211   return code;
212 }
213