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