xref: /plan9/sys/src/cmd/gs/src/gdevsppr.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1992, 1993, 1996, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gdevsppr.c,v 1.9 2004/11/03 07:34:03 giles Exp $*/
18 /* SPARCprinter driver for Ghostscript */
19 #include "gdevprn.h"
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <sys/ioccom.h>
23 #include <unbdev/lpviio.h>
24 
25 /*
26    Thanks to Martin Schulte (schulte@thp.Uni-Koeln.DE) for contributing
27    this driver to Ghostscript.  He supplied the following notes.
28 
29 The device-driver (normally) returns two differnt types of Error-Conditions,
30 FATALS and WARNINGS. In case of a fatal, the print routine returns -1, in
31 case of a warning (such as paper out), a string describing the error is
32 printed to stderr and the output-operation is repeated after five seconds.
33 
34 A problem is that not all possible errors seem to return the correct error,
35 under some circumstance I get the same response as if an error repeated,
36 that's why there is this the strange code about guessing the error.
37 
38 I didn't implement asynchronous IO (yet), because "`normal"' multipage-
39 printings like TEX-Output seem to be printed with the maximum speed whereas
40 drawings normally occur as one-page outputs, where asynchronous IO doesn't
41 help anyway.
42 */
43 
44 private dev_proc_open_device(sparc_open);
45 private dev_proc_print_page(sparc_print_page);
46 
47 #define SPARC_MARGINS_A4	0.15, 0.12, 0.12, 0.15
48 #define SPARC_MARGINS_LETTER	0.15, 0.12, 0.12, 0.15
49 
50 gx_device_procs prn_sparc_procs =
51   prn_procs(sparc_open, gdev_prn_output_page, gdev_prn_close);
52 
53 const gx_device_printer far_data gs_sparc_device =
54 prn_device(prn_sparc_procs,
55   "sparc",
56   DEFAULT_WIDTH_10THS,DEFAULT_HEIGHT_10THS,
57   400,400,
58   0,0,0,0,
59   1,
60   sparc_print_page);
61 
62 /* Open the printer, and set the margins. */
63 private int
sparc_open(gx_device * pdev)64 sparc_open(gx_device *pdev)
65 {	/* Change the margins according to the paper size. */
66 	const float *m;
67 	static const float m_a4[4] = { SPARC_MARGINS_A4 };
68 	static const float m_letter[4] = { SPARC_MARGINS_LETTER };
69 
70 	m = (pdev->height / pdev->y_pixels_per_inch >= 11.1 ? m_a4 : m_letter);
71 	gx_device_set_margins(pdev, m, true);
72 	return gdev_prn_open(pdev);
73 }
74 
75 char *errmsg[]={
76   "EMOTOR",
77   "EROS",
78   "EFUSER",
79   "XEROFAIL",
80   "ILCKOPEN",
81   "NOTRAY",
82   "NOPAPR",
83   "XITJAM",
84   "MISFEED",
85   "WDRUMX",
86   "WDEVEX",
87   "NODRUM",
88   "NODEVE",
89   "EDRUMX",
90   "EDEVEX",
91   "ENGCOLD",
92   "TIMEOUT",
93   "EDMA",
94   "ESERIAL"
95   };
96 
97 /* The static buffer is unfortunate.... */
98 static char err_buffer[80];
99 private char *
err_code_string(int err_code)100 err_code_string(int err_code)
101   {
102   if ((err_code<EMOTOR)||(err_code>ESERIAL))
103     {
104     sprintf(err_buffer,"err_code out of range: %d",err_code);
105     return err_buffer;
106     }
107   return errmsg[err_code];
108   }
109 
110 int warning=0;
111 
112 private int
sparc_print_page(gx_device_printer * pdev,FILE * prn)113 sparc_print_page(gx_device_printer *pdev, FILE *prn)
114   {
115   struct lpvi_page lpvipage;
116   struct lpvi_err lpvierr;
117   char *out_buf;
118   int out_size;
119   if (ioctl(fileno(prn),LPVIIOC_GETPAGE,&lpvipage)!=0)
120     {
121     errprintf("sparc_print_page: LPVIIOC_GETPAGE failed\n");
122     return -1;
123     }
124   lpvipage.bitmap_width=gdev_mem_bytes_per_scan_line((gx_device *)pdev);
125   lpvipage.page_width=lpvipage.bitmap_width*8;
126   lpvipage.page_length=pdev->height;
127   lpvipage.resolution = (pdev->x_pixels_per_inch == 300 ? DPI300 : DPI400);
128   if (ioctl(fileno(prn),LPVIIOC_SETPAGE,&lpvipage)!=0)
129     {
130     errprintf("sparc_print_page: LPVIIOC_SETPAGE failed\n");
131     return -1;
132     }
133   out_size=lpvipage.bitmap_width*lpvipage.page_length;
134   out_buf=gs_malloc(pdev->memory, out_size,1,"sparc_print_page: out_buf");
135   gdev_prn_copy_scan_lines(pdev,0,out_buf,out_size);
136   while (write(fileno(prn),out_buf,out_size)!=out_size)
137     {
138     if (ioctl(fileno(prn),LPVIIOC_GETERR,&lpvierr)!=0)
139       {
140       errprintf("sparc_print_page: LPVIIOC_GETERR failed\n");
141       return -1;
142       }
143     switch (lpvierr.err_type)
144       {
145       case 0:
146 	if (warning==0)
147           {
148           errprintf(
149             "sparc_print_page: Printer Problem with unknown reason...");
150           dflush();
151           warning=1;
152           }
153 	sleep(5);
154 	break;
155       case ENGWARN:
156 	errprintf(
157           "sparc_print_page: Printer-Warning: %s...",
158           err_code_string(lpvierr.err_code));
159 	dflush();
160 	warning=1;
161 	sleep(5);
162 	break;
163       case ENGFATL:
164 	errprintf(
165           "sparc_print_page: Printer-Fatal: %s\n",
166           err_code_string(lpvierr.err_code));
167 	return -1;
168       case EDRVR:
169 	errprintf(
170           "sparc_print_page: Interface/driver error: %s\n",
171           err_code_string(lpvierr.err_code));
172 	return -1;
173       default:
174 	errprintf(
175           "sparc_print_page: Unknown err_type=%d(err_code=%d)\n",
176           lpvierr.err_type,lpvierr.err_code);
177 	return -1;
178       }
179     }
180   if (warning==1)
181     {
182     errprintf("OK.\n");
183     warning=0;
184     }
185   gs_free(pdev->memory, out_buf,out_size,1,"sparc_print_page: out_buf");
186   return 0;
187   }
188