xref: /plan9-contrib/sys/src/cmd/gs/src/gp_os2pr.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1*593dc095SDavid du Colombier /* Copyright (C) 2004 artofcode LLC.  All rights reserved.
2*593dc095SDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
5*593dc095SDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
9*593dc095SDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15*593dc095SDavid du Colombier */
16*593dc095SDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: gp_os2pr.c,v 1.1 2004/09/14 06:45:55 ghostgum Exp $ */
18*593dc095SDavid du Colombier /* %printer% IODevice */
19*593dc095SDavid du Colombier 
20*593dc095SDavid du Colombier #define INCL_DOS
21*593dc095SDavid du Colombier #define INCL_SPL
22*593dc095SDavid du Colombier #define INCL_SPLDOSPRINT
23*593dc095SDavid du Colombier #define INCL_SPLERRORS
24*593dc095SDavid du Colombier #define INCL_BASE
25*593dc095SDavid du Colombier #define INCL_ERRORS
26*593dc095SDavid du Colombier #define INCL_WIN
27*593dc095SDavid du Colombier #include <os2.h>
28*593dc095SDavid du Colombier 
29*593dc095SDavid du Colombier #include "errno_.h"
30*593dc095SDavid du Colombier #include "stdio_.h"
31*593dc095SDavid du Colombier #include "string_.h"
32*593dc095SDavid du Colombier #include "gp.h"
33*593dc095SDavid du Colombier #include "gscdefs.h"
34*593dc095SDavid du Colombier #include "gserrors.h"
35*593dc095SDavid du Colombier #include "gserror.h"
36*593dc095SDavid du Colombier #include "gstypes.h"
37*593dc095SDavid du Colombier #include "gsmemory.h"		/* for gxiodev.h */
38*593dc095SDavid du Colombier #include "gxiodev.h"
39*593dc095SDavid du Colombier 
40*593dc095SDavid du Colombier /* The OS/2 printer IODevice */
41*593dc095SDavid du Colombier 
42*593dc095SDavid du Colombier /*
43*593dc095SDavid du Colombier  * This allows an OS/2 printer to be specified as an
44*593dc095SDavid du Colombier  * output using
45*593dc095SDavid du Colombier  *  -sOutputFile="%printer%AppleLas"
46*593dc095SDavid du Colombier  * where "AppleLas" is the physical name of the queue.
47*593dc095SDavid du Colombier  *
48*593dc095SDavid du Colombier  * If you don't supply a printer name you will get
49*593dc095SDavid du Colombier  *  Error: /undefinedfilename in --.outputpage--
50*593dc095SDavid du Colombier  * If the printer name is invalid you will get
51*593dc095SDavid du Colombier  *  Error: /invalidfileaccess in --.outputpage--
52*593dc095SDavid du Colombier  *
53*593dc095SDavid du Colombier  * This is implemented by writing to a temporary file
54*593dc095SDavid du Colombier  * then copying it to the spooler.
55*593dc095SDavid du Colombier  *
56*593dc095SDavid du Colombier  * A better method would be to return a file pointer
57*593dc095SDavid du Colombier  * to the write end of a pipe, and starting a thread
58*593dc095SDavid du Colombier  * which reads the pipe and writes to an OS/2 printer.
59*593dc095SDavid du Colombier  * This method didn't work properly on the second
60*593dc095SDavid du Colombier  * thread within ghostscript.
61*593dc095SDavid du Colombier  */
62*593dc095SDavid du Colombier 
63*593dc095SDavid du Colombier private iodev_proc_init(os2_printer_init);
64*593dc095SDavid du Colombier private iodev_proc_fopen(os2_printer_fopen);
65*593dc095SDavid du Colombier private iodev_proc_fclose(os2_printer_fclose);
66*593dc095SDavid du Colombier const gx_io_device gs_iodev_printer = {
67*593dc095SDavid du Colombier     "%printer%", "FileSystem",
68*593dc095SDavid du Colombier     {os2_printer_init, iodev_no_open_device,
69*593dc095SDavid du Colombier      NULL /*iodev_os_open_file */ , os2_printer_fopen, os2_printer_fclose,
70*593dc095SDavid du Colombier      iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,
71*593dc095SDavid du Colombier      iodev_no_enumerate_files, NULL, NULL,
72*593dc095SDavid du Colombier      iodev_no_get_params, iodev_no_put_params
73*593dc095SDavid du Colombier     }
74*593dc095SDavid du Colombier };
75*593dc095SDavid du Colombier 
76*593dc095SDavid du Colombier typedef struct os2_printer_s {
77*593dc095SDavid du Colombier     char queue[gp_file_name_sizeof];
78*593dc095SDavid du Colombier     char filename[gp_file_name_sizeof];
79*593dc095SDavid du Colombier } os2_printer_t;
80*593dc095SDavid du Colombier 
81*593dc095SDavid du Colombier /* The file device procedures */
82*593dc095SDavid du Colombier private int
os2_printer_init(gx_io_device * iodev,gs_memory_t * mem)83*593dc095SDavid du Colombier os2_printer_init(gx_io_device * iodev, gs_memory_t * mem)
84*593dc095SDavid du Colombier {
85*593dc095SDavid du Colombier     /* state -> structure containing thread handle */
86*593dc095SDavid du Colombier     iodev->state = gs_alloc_bytes(mem, sizeof(os2_printer_t),
87*593dc095SDavid du Colombier 	"os2_printer_init");
88*593dc095SDavid du Colombier     if (iodev->state == NULL)
89*593dc095SDavid du Colombier         return_error(gs_error_VMerror);
90*593dc095SDavid du Colombier     memset(iodev->state, 0, sizeof(os2_printer_t));
91*593dc095SDavid du Colombier     return 0;
92*593dc095SDavid du Colombier }
93*593dc095SDavid du Colombier 
94*593dc095SDavid du Colombier 
95*593dc095SDavid du Colombier private int
os2_printer_fopen(gx_io_device * iodev,const char * fname,const char * access,FILE ** pfile,char * rfname,uint rnamelen)96*593dc095SDavid du Colombier os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
97*593dc095SDavid du Colombier 	   FILE ** pfile, char *rfname, uint rnamelen)
98*593dc095SDavid du Colombier {
99*593dc095SDavid du Colombier     os2_printer_t *pr = (os2_printer_t *)iodev->state;
100*593dc095SDavid du Colombier     char driver_name[256];
101*593dc095SDavid du Colombier 
102*593dc095SDavid du Colombier     /* Make sure that printer exists. */
103*593dc095SDavid du Colombier     if (pm_find_queue(fname, driver_name)) {
104*593dc095SDavid du Colombier 	/* error, list valid queue names */
105*593dc095SDavid du Colombier 	eprintf("Invalid queue name.  Use one of:\n");
106*593dc095SDavid du Colombier 	pm_find_queue(NULL, NULL);
107*593dc095SDavid du Colombier 	return_error(gs_error_undefinedfilename);
108*593dc095SDavid du Colombier     }
109*593dc095SDavid du Colombier 
110*593dc095SDavid du Colombier     strncpy(pr->queue, fname, sizeof(pr->queue)-1);
111*593dc095SDavid du Colombier 
112*593dc095SDavid du Colombier     /* Create a temporary file */
113*593dc095SDavid du Colombier     *pfile = gp_open_scratch_file("gs", pr->filename, access);
114*593dc095SDavid du Colombier     if (*pfile == NULL)
115*593dc095SDavid du Colombier 	return_error(gs_fopen_errno_to_code(errno));
116*593dc095SDavid du Colombier 
117*593dc095SDavid du Colombier     return 0;
118*593dc095SDavid du Colombier }
119*593dc095SDavid du Colombier 
120*593dc095SDavid du Colombier private int
os2_printer_fclose(gx_io_device * iodev,FILE * file)121*593dc095SDavid du Colombier os2_printer_fclose(gx_io_device * iodev, FILE * file)
122*593dc095SDavid du Colombier {
123*593dc095SDavid du Colombier     os2_printer_t *pr = (os2_printer_t *)iodev->state;
124*593dc095SDavid du Colombier     fclose(file);
125*593dc095SDavid du Colombier     pm_spool(pr->filename, pr->queue);
126*593dc095SDavid du Colombier     unlink(pr->filename);
127*593dc095SDavid du Colombier     return 0;
128*593dc095SDavid du Colombier }
129*593dc095SDavid du Colombier 
130