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