xref: /plan9/sys/src/cmd/gs/src/gs16spl.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /* Copyright (C) 1995, Russell Lang.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid 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.
97dd7cddfSDavid 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.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: gs16spl.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
187dd7cddfSDavid du Colombier /* 16-bit access to print spooler from Win32s */
197dd7cddfSDavid du Colombier /* by Russell Lang */
207dd7cddfSDavid du Colombier /* 1995-11-23 */
217dd7cddfSDavid du Colombier 
227dd7cddfSDavid du Colombier /*
237dd7cddfSDavid du Colombier  * Ghostscript produces printer specific output
247dd7cddfSDavid du Colombier  * which must be given to the print spooler.
257dd7cddfSDavid du Colombier  * Under Win16, the APIs OpenJob, WriteSpool etc. are used
267dd7cddfSDavid du Colombier  * Under Win32 and Windows 95/NT, the APIs OpenPrinter, WritePrinter etc.
277dd7cddfSDavid du Colombier  * are used.
287dd7cddfSDavid du Colombier  * Under Win32s, the 16-bit spooler APIs are not available, and the
297dd7cddfSDavid du Colombier  * 32-bit spooler APIs are not implemented.
307dd7cddfSDavid du Colombier  * This purpose of this application is to provide a means for the Win32s
317dd7cddfSDavid du Colombier  * version of Ghostscript to send output to the 16-bit spooler.
327dd7cddfSDavid du Colombier  */
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier /*
357dd7cddfSDavid du Colombier  * Usage:  gs16spl port filename
367dd7cddfSDavid du Colombier  *
377dd7cddfSDavid du Colombier  * filename will be sent to the spooler port.
387dd7cddfSDavid du Colombier  */
397dd7cddfSDavid du Colombier 
407dd7cddfSDavid du Colombier 
417dd7cddfSDavid du Colombier #define STRICT
427dd7cddfSDavid du Colombier #include <windows.h>
437dd7cddfSDavid du Colombier #include <stdio.h>
447dd7cddfSDavid du Colombier #include <stdlib.h>
457dd7cddfSDavid du Colombier #include <string.h>
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier #define ID_TEXT 100
487dd7cddfSDavid du Colombier 
497dd7cddfSDavid du Colombier /* documented in Device Driver Adaptation Guide */
507dd7cddfSDavid du Colombier /* Prototypes taken from print.h */
517dd7cddfSDavid du Colombier DECLARE_HANDLE(HPJOB);
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier HPJOB WINAPI OpenJob(LPSTR, LPSTR, HPJOB);
547dd7cddfSDavid du Colombier int WINAPI StartSpoolPage(HPJOB);
557dd7cddfSDavid du Colombier int WINAPI EndSpoolPage(HPJOB);
567dd7cddfSDavid du Colombier int WINAPI WriteSpool(HPJOB, LPSTR, int);
577dd7cddfSDavid du Colombier int WINAPI CloseJob(HPJOB);
587dd7cddfSDavid du Colombier int WINAPI DeleteJob(HPJOB, int);
597dd7cddfSDavid du Colombier int WINAPI WriteDialog(HPJOB, LPSTR, int);
607dd7cddfSDavid du Colombier int WINAPI DeleteSpoolPage(HPJOB);
617dd7cddfSDavid du Colombier 
627dd7cddfSDavid du Colombier #define MAXSTR 256
637dd7cddfSDavid du Colombier #define PRINT_BUF_SIZE 16384
647dd7cddfSDavid du Colombier 
657dd7cddfSDavid du Colombier HPJOB hJob;
667dd7cddfSDavid du Colombier HWND hwndspl;
677dd7cddfSDavid du Colombier DLGPROC lpfnSpoolProc;
687dd7cddfSDavid du Colombier HINSTANCE phInstance;
697dd7cddfSDavid du Colombier char port[MAXSTR];
707dd7cddfSDavid du Colombier char filename[MAXSTR];
717dd7cddfSDavid du Colombier char error_message[MAXSTR];
727dd7cddfSDavid du Colombier int error;
737dd7cddfSDavid du Colombier 
747dd7cddfSDavid du Colombier char szAppName[] = "GS Win32s/Win16 spooler";
757dd7cddfSDavid du Colombier 
767dd7cddfSDavid du Colombier /* returns TRUE on success, FALSE on failure */
777dd7cddfSDavid du Colombier int
spoolfile(char * portname,char * filename)787dd7cddfSDavid du Colombier spoolfile(char *portname, char *filename)
797dd7cddfSDavid du Colombier {
807dd7cddfSDavid du Colombier     FILE *f;
817dd7cddfSDavid du Colombier     char *buffer;
827dd7cddfSDavid du Colombier     char pcdone[64];
837dd7cddfSDavid du Colombier     long ldone;
847dd7cddfSDavid du Colombier     long lsize;
857dd7cddfSDavid du Colombier     int count;
867dd7cddfSDavid du Colombier     MSG msg;
877dd7cddfSDavid du Colombier 
887dd7cddfSDavid du Colombier     if ((*portname == '\0') || (*filename == '\0')) {
897dd7cddfSDavid du Colombier 	strcpy(error_message, "Usage: gs16spl port filename");
907dd7cddfSDavid du Colombier 	return FALSE;
917dd7cddfSDavid du Colombier     }
927dd7cddfSDavid du Colombier     if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL)
937dd7cddfSDavid du Colombier 	return FALSE;
947dd7cddfSDavid du Colombier 
957dd7cddfSDavid du Colombier     if ((f = fopen(filename, "rb")) == (FILE *) NULL) {
967dd7cddfSDavid du Colombier 	sprintf(error_message, "Can't open %s", filename);
977dd7cddfSDavid du Colombier 	free(buffer);
987dd7cddfSDavid du Colombier 	return FALSE;
997dd7cddfSDavid du Colombier     }
1007dd7cddfSDavid du Colombier     fseek(f, 0L, SEEK_END);
1017dd7cddfSDavid du Colombier     lsize = ftell(f);
1027dd7cddfSDavid du Colombier     if (lsize <= 0)
1037dd7cddfSDavid du Colombier 	lsize = 1;
1047dd7cddfSDavid du Colombier     fseek(f, 0L, SEEK_SET);
1057dd7cddfSDavid du Colombier     ldone = 0;
1067dd7cddfSDavid du Colombier 
1077dd7cddfSDavid du Colombier     hJob = OpenJob(portname, filename, (HDC) NULL);
1087dd7cddfSDavid du Colombier     switch ((int)hJob) {
1097dd7cddfSDavid du Colombier 	case SP_APPABORT:
1107dd7cddfSDavid du Colombier 	case SP_ERROR:
1117dd7cddfSDavid du Colombier 	case SP_OUTOFDISK:
1127dd7cddfSDavid du Colombier 	case SP_OUTOFMEMORY:
1137dd7cddfSDavid du Colombier 	case SP_USERABORT:
1147dd7cddfSDavid du Colombier 	    fclose(f);
1157dd7cddfSDavid du Colombier 	    free(buffer);
1167dd7cddfSDavid du Colombier 	    return FALSE;
1177dd7cddfSDavid du Colombier     }
1187dd7cddfSDavid du Colombier     if (StartSpoolPage(hJob) < 0)
1197dd7cddfSDavid du Colombier 	error = TRUE;
1207dd7cddfSDavid du Colombier 
1217dd7cddfSDavid du Colombier     while (!error
1227dd7cddfSDavid du Colombier 	   && (count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0) {
1237dd7cddfSDavid du Colombier 	if (WriteSpool(hJob, buffer, count) < 0)
1247dd7cddfSDavid du Colombier 	    error = TRUE;
1257dd7cddfSDavid du Colombier 	ldone += count;
1267dd7cddfSDavid du Colombier 	sprintf(pcdone, "%d%% written to %s", (int)(ldone * 100 / lsize), portname);
1277dd7cddfSDavid du Colombier 	SetWindowText(GetDlgItem(hwndspl, ID_TEXT), pcdone);
1287dd7cddfSDavid du Colombier 	while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
1297dd7cddfSDavid du Colombier 	    TranslateMessage(&msg);
1307dd7cddfSDavid du Colombier 	    DispatchMessage(&msg);
1317dd7cddfSDavid du Colombier 	}
1327dd7cddfSDavid du Colombier     }
1337dd7cddfSDavid du Colombier     free(buffer);
1347dd7cddfSDavid du Colombier     fclose(f);
1357dd7cddfSDavid du Colombier 
1367dd7cddfSDavid du Colombier     EndSpoolPage(hJob);
1377dd7cddfSDavid du Colombier     if (error)
1387dd7cddfSDavid du Colombier 	DeleteJob(hJob, 0);
1397dd7cddfSDavid du Colombier     else
1407dd7cddfSDavid du Colombier 	CloseJob(hJob);
1417dd7cddfSDavid du Colombier     return !error;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier 
1447dd7cddfSDavid du Colombier 
1457dd7cddfSDavid du Colombier /* Modeless dialog box - main window */
1467dd7cddfSDavid du Colombier BOOL CALLBACK _export
SpoolDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)1477dd7cddfSDavid du Colombier SpoolDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1487dd7cddfSDavid du Colombier {
1497dd7cddfSDavid du Colombier     switch (message) {
1507dd7cddfSDavid du Colombier 	case WM_INITDIALOG:
1517dd7cddfSDavid du Colombier 	    SetWindowText(hDlg, szAppName);
1527dd7cddfSDavid du Colombier 	    return TRUE;
1537dd7cddfSDavid du Colombier 	case WM_COMMAND:
1547dd7cddfSDavid du Colombier 	    switch (LOWORD(wParam)) {
1557dd7cddfSDavid du Colombier 		case IDCANCEL:
1567dd7cddfSDavid du Colombier 		    error = TRUE;
1577dd7cddfSDavid du Colombier 		    DestroyWindow(hDlg);
1587dd7cddfSDavid du Colombier 		    EndDialog(hDlg, 0);
1597dd7cddfSDavid du Colombier 		    PostQuitMessage(0);
1607dd7cddfSDavid du Colombier 		    return TRUE;
1617dd7cddfSDavid du Colombier 	    }
1627dd7cddfSDavid du Colombier     }
1637dd7cddfSDavid du Colombier     return FALSE;
1647dd7cddfSDavid du Colombier }
1657dd7cddfSDavid du Colombier 
1667dd7cddfSDavid du Colombier 
1677dd7cddfSDavid du Colombier void
init_window(LPSTR cmdline)1687dd7cddfSDavid du Colombier init_window(LPSTR cmdline)
1697dd7cddfSDavid du Colombier {
1707dd7cddfSDavid du Colombier     LPSTR s;
1717dd7cddfSDavid du Colombier     char *d;
1727dd7cddfSDavid du Colombier 
1737dd7cddfSDavid du Colombier     s = cmdline;
1747dd7cddfSDavid du Colombier     /* skip leading spaces */
1757dd7cddfSDavid du Colombier     while (*s && *s == ' ')
1767dd7cddfSDavid du Colombier 	s++;
1777dd7cddfSDavid du Colombier     /* copy port name */
1787dd7cddfSDavid du Colombier     d = port;
1797dd7cddfSDavid du Colombier     while (*s && *s != ' ')
1807dd7cddfSDavid du Colombier 	*d++ = *s++;
1817dd7cddfSDavid du Colombier     *d = '\0';
1827dd7cddfSDavid du Colombier     /* skip spaces */
1837dd7cddfSDavid du Colombier     while (*s && *s == ' ')
1847dd7cddfSDavid du Colombier 	s++;
1857dd7cddfSDavid du Colombier     /* copy port name */
1867dd7cddfSDavid du Colombier     d = filename;
1877dd7cddfSDavid du Colombier     while (*s && *s != ' ')
1887dd7cddfSDavid du Colombier 	*d++ = *s++;
1897dd7cddfSDavid du Colombier     *d = '\0';
1907dd7cddfSDavid du Colombier 
1917dd7cddfSDavid du Colombier     lpfnSpoolProc = (DLGPROC) MakeProcInstance((FARPROC) SpoolDlgProc, phInstance);
1927dd7cddfSDavid du Colombier     hwndspl = CreateDialog(phInstance, "SpoolDlgBox", HWND_DESKTOP, lpfnSpoolProc);
1937dd7cddfSDavid du Colombier 
1947dd7cddfSDavid du Colombier     return;
1957dd7cddfSDavid du Colombier }
1967dd7cddfSDavid du Colombier 
1977dd7cddfSDavid du Colombier int PASCAL
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int cmdShow)1987dd7cddfSDavid du Colombier WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
1997dd7cddfSDavid du Colombier {
2007dd7cddfSDavid du Colombier     MSG msg;
2017dd7cddfSDavid du Colombier 
2027dd7cddfSDavid du Colombier     phInstance = hInstance;
2037dd7cddfSDavid du Colombier 
2047dd7cddfSDavid du Colombier     init_window(lpszCmdLine);
2057dd7cddfSDavid du Colombier     ShowWindow(hwndspl, cmdShow);
2067dd7cddfSDavid du Colombier 
2077dd7cddfSDavid du Colombier     if (!spoolfile(port, filename)) {
2087dd7cddfSDavid du Colombier 	/* wait, showing error message */
2097dd7cddfSDavid du Colombier 	SetWindowText(GetDlgItem(hwndspl, ID_TEXT), error_message);
2107dd7cddfSDavid du Colombier 	while (GetMessage(&msg, (HWND) NULL, 0, 0)) {
2117dd7cddfSDavid du Colombier 	    TranslateMessage(&msg);
2127dd7cddfSDavid du Colombier 	    DispatchMessage(&msg);
2137dd7cddfSDavid du Colombier 	}
2147dd7cddfSDavid du Colombier     }
2157dd7cddfSDavid du Colombier     DestroyWindow(hwndspl);
2167dd7cddfSDavid du Colombier     FreeProcInstance((FARPROC) lpfnSpoolProc);
2177dd7cddfSDavid du Colombier     return 0;
2187dd7cddfSDavid du Colombier }
219