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