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