xref: /plan9/sys/src/cmd/gs/src/gs16spl.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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