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