1 /* Copyright (C) 1995, Russell Lang. 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: gs16spl.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
18 /* 16-bit access to print spooler from Win32s */
19 /* by Russell Lang */
20 /* 1995-11-23 */
21
22 /*
23 * Ghostscript produces printer specific output
24 * which must be given to the print spooler.
25 * Under Win16, the APIs OpenJob, WriteSpool etc. are used
26 * Under Win32 and Windows 95/NT, the APIs OpenPrinter, WritePrinter etc.
27 * are used.
28 * Under Win32s, the 16-bit spooler APIs are not available, and the
29 * 32-bit spooler APIs are not implemented.
30 * This purpose of this application is to provide a means for the Win32s
31 * version of Ghostscript to send output to the 16-bit spooler.
32 */
33
34 /*
35 * Usage: gs16spl port filename
36 *
37 * filename will be sent to the spooler port.
38 */
39
40
41 #define STRICT
42 #include <windows.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46
47 #define ID_TEXT 100
48
49 /* documented in Device Driver Adaptation Guide */
50 /* Prototypes taken from print.h */
51 DECLARE_HANDLE(HPJOB);
52
53 HPJOB WINAPI OpenJob(LPSTR, LPSTR, HPJOB);
54 int WINAPI StartSpoolPage(HPJOB);
55 int WINAPI EndSpoolPage(HPJOB);
56 int WINAPI WriteSpool(HPJOB, LPSTR, int);
57 int WINAPI CloseJob(HPJOB);
58 int WINAPI DeleteJob(HPJOB, int);
59 int WINAPI WriteDialog(HPJOB, LPSTR, int);
60 int WINAPI DeleteSpoolPage(HPJOB);
61
62 #define MAXSTR 256
63 #define PRINT_BUF_SIZE 16384
64
65 HPJOB hJob;
66 HWND hwndspl;
67 DLGPROC lpfnSpoolProc;
68 HINSTANCE phInstance;
69 char port[MAXSTR];
70 char filename[MAXSTR];
71 char error_message[MAXSTR];
72 int error;
73
74 char szAppName[] = "GS Win32s/Win16 spooler";
75
76 /* returns TRUE on success, FALSE on failure */
77 int
spoolfile(char * portname,char * filename)78 spoolfile(char *portname, char *filename)
79 {
80 FILE *f;
81 char *buffer;
82 char pcdone[64];
83 long ldone;
84 long lsize;
85 int count;
86 MSG msg;
87
88 if ((*portname == '\0') || (*filename == '\0')) {
89 strcpy(error_message, "Usage: gs16spl port filename");
90 return FALSE;
91 }
92 if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL)
93 return FALSE;
94
95 if ((f = fopen(filename, "rb")) == (FILE *) NULL) {
96 sprintf(error_message, "Can't open %s", filename);
97 free(buffer);
98 return FALSE;
99 }
100 fseek(f, 0L, SEEK_END);
101 lsize = ftell(f);
102 if (lsize <= 0)
103 lsize = 1;
104 fseek(f, 0L, SEEK_SET);
105 ldone = 0;
106
107 hJob = OpenJob(portname, filename, (HDC) NULL);
108 switch ((int)hJob) {
109 case SP_APPABORT:
110 case SP_ERROR:
111 case SP_OUTOFDISK:
112 case SP_OUTOFMEMORY:
113 case SP_USERABORT:
114 fclose(f);
115 free(buffer);
116 return FALSE;
117 }
118 if (StartSpoolPage(hJob) < 0)
119 error = TRUE;
120
121 while (!error
122 && (count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0) {
123 if (WriteSpool(hJob, buffer, count) < 0)
124 error = TRUE;
125 ldone += count;
126 sprintf(pcdone, "%d%% written to %s", (int)(ldone * 100 / lsize), portname);
127 SetWindowText(GetDlgItem(hwndspl, ID_TEXT), pcdone);
128 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
129 TranslateMessage(&msg);
130 DispatchMessage(&msg);
131 }
132 }
133 free(buffer);
134 fclose(f);
135
136 EndSpoolPage(hJob);
137 if (error)
138 DeleteJob(hJob, 0);
139 else
140 CloseJob(hJob);
141 return !error;
142 }
143
144
145 /* Modeless dialog box - main window */
146 BOOL CALLBACK _export
SpoolDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)147 SpoolDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
148 {
149 switch (message) {
150 case WM_INITDIALOG:
151 SetWindowText(hDlg, szAppName);
152 return TRUE;
153 case WM_COMMAND:
154 switch (LOWORD(wParam)) {
155 case IDCANCEL:
156 error = TRUE;
157 DestroyWindow(hDlg);
158 EndDialog(hDlg, 0);
159 PostQuitMessage(0);
160 return TRUE;
161 }
162 }
163 return FALSE;
164 }
165
166
167 void
init_window(LPSTR cmdline)168 init_window(LPSTR cmdline)
169 {
170 LPSTR s;
171 char *d;
172
173 s = cmdline;
174 /* skip leading spaces */
175 while (*s && *s == ' ')
176 s++;
177 /* copy port name */
178 d = port;
179 while (*s && *s != ' ')
180 *d++ = *s++;
181 *d = '\0';
182 /* skip spaces */
183 while (*s && *s == ' ')
184 s++;
185 /* copy port name */
186 d = filename;
187 while (*s && *s != ' ')
188 *d++ = *s++;
189 *d = '\0';
190
191 lpfnSpoolProc = (DLGPROC) MakeProcInstance((FARPROC) SpoolDlgProc, phInstance);
192 hwndspl = CreateDialog(phInstance, "SpoolDlgBox", HWND_DESKTOP, lpfnSpoolProc);
193
194 return;
195 }
196
197 int PASCAL
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int cmdShow)198 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
199 {
200 MSG msg;
201
202 phInstance = hInstance;
203
204 init_window(lpszCmdLine);
205 ShowWindow(hwndspl, cmdShow);
206
207 if (!spoolfile(port, filename)) {
208 /* wait, showing error message */
209 SetWindowText(GetDlgItem(hwndspl, ID_TEXT), error_message);
210 while (GetMessage(&msg, (HWND) NULL, 0, 0)) {
211 TranslateMessage(&msg);
212 DispatchMessage(&msg);
213 }
214 }
215 DestroyWindow(hwndspl);
216 FreeProcInstance((FARPROC) lpfnSpoolProc);
217 return 0;
218 }
219