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