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 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 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 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 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