To run Aladdin Ghostscript 3.33 you also need gs333ini.zip
obtained from the same place as this zip file

This EXE is for Win32s.

This is Aladdin Ghostscript 3.33 with the following patches.
The patches are:
1. Add mswinpr2 device for Win16 and Win32.  This is a new driver -
   please report any problems to rjl@aladdin.com.
2. Turn on optimiser for OS/2
3. Add PDF support to Win32 and OS/2
4. Add more device support for Win32 and OS/2
5. Fix bug in laserjet family devices.
6. Avoid BC++ 4.5 compiler objection to gdevlbp8.c

Compilation has been with BC++ 4.5 for Win16 and Win32,
and with GCC/EMX 0.9a for OS/2.

rjl 1995-04-29


diff -cr ./bcwin.mak ../bcwin.mak
*** ./bcwin.mak	Mon Mar 27 01:44:24 1995
--- ../bcwin.mak	Sat Apr 29 08:41:04 1995
***************
*** 194,200 ****
  LCT=/v
  !else
  CT=-y
! LCT=/m /l
  !endif
  
  GENOPT=$(CP) $(CS) $(CD) $(CT)
--- 194,200 ----
  LCT=/v
  !else
  CT=-y
! LCT=/m /l /s
  !endif
  
  GENOPT=$(CP) $(CS) $(CD) $(CT)
***************
*** 230,238 ****
  # Choose the device(s) to include.  See devs.mak for details.
  
  !if $(GSDLL)
! DEVICE_DEVS=mswindll.dev mswin.dev mswinprn.dev
  !else
! DEVICE_DEVS=mswin.dev mswinprn.dev
  !endif
  DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
  DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
--- 230,238 ----
  # Choose the device(s) to include.  See devs.mak for details.
  
  !if $(GSDLL)
! DEVICE_DEVS=mswindll.dev mswin.dev mswinprn.dev mswinpr2.dev
  !else
! DEVICE_DEVS=mswin.dev mswinprn.dev mswinpr2.dev
  !endif
  DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
  DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
diff -cr ./bcwin32.mak ../bcwin32.mak
*** ./bcwin32.mak	Sat Mar 18 16:27:54 1995
--- ../bcwin32.mak	Sat Apr 29 08:40:22 1995
***************
*** 207,228 ****
  
  # Choose the language feature(s) to include.  See gs.mak for details.
  # Since we only support running in enhanced mode, which provides
! # virtual memory, we include a fair number of drivers, but we still can't
! # exceed 64K of static data.
  
! FEATURE_DEVS=level2.dev
  
  # Choose the device(s) to include.  See devs.mak for details.
  
  !if $(GSDLL)
! DEVICE_DEVS=mswindll.dev mswin.dev mswinprn.dev
  !else
! DEVICE_DEVS=mswin.dev mswinprn.dev
  !endif
  DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
  DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
! DEVICE_DEVS6=epson.dev eps9high.dev ibmpro.dev st800.dev bj10e.dev bj200.dev
! DEVICE_DEVS8=bmpmono.dev bmp16.dev bmp256.dev bmp16m.dev pcxmono.dev pcx16.dev pcx256.dev
  DEVICE_DEVS9=psmono.dev bit.dev bitrgb.dev bitcmyk.dev
  DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
  !include "gs.mak"
--- 207,230 ----
  
  # Choose the language feature(s) to include.  See gs.mak for details.
  # Since we only support running in enhanced mode, which provides
! # virtual memory, we include a fair number of drivers, 
  
! FEATURE_DEVS=level2.dev pdf.dev
  
  # Choose the device(s) to include.  See devs.mak for details.
  
  !if $(GSDLL)
! DEVICE_DEVS=mswindll.dev mswin.dev mswinprn.dev mswinpr2.dev
  !else
! DEVICE_DEVS=mswin.dev mswinprn.dev mswinpr2.dev
  !endif
+ DEVICE_DEVS2=epson.dev eps9high.dev eps9mid.dev epsonc.dev ibmpro.dev
  DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
  DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
! DEVICE_DEVS5=djet500c.dev declj250.dev lj250.dev jetp3852.dev r4081.dev lbp8.dev
! DEVICE_DEVS6=st800.dev stcolor.dev bj10e.dev bj200.dev m8510.dev necp6.dev
! DEVICE_DEVS7=t4693d2.dev t4693d4.dev t4693d8.dev tek4696.dev
! DEVICE_DEVS8=bmpmono.dev bmp16.dev bmp256.dev bmp16m.dev pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev
  DEVICE_DEVS9=psmono.dev bit.dev bitrgb.dev bitcmyk.dev
  DEVICE_DEVS10=tiffcrle.dev tiffg3.dev tiffg32d.dev tiffg4.dev tifflzw.dev tiffpack.dev
  !include "gs.mak"
diff -cr ./devs.mak ../devs.mak
*** ./devs.mak	Fri Mar 31 15:01:32 1995
--- ../devs.mak	Sat Apr 29 08:35:48 1995
***************
*** 45,51 ****
  #   MS Windows:
  #	mswin	Microsoft Windows 3.0, 3.1   [MS Windows only]
  #	mswindll  Microsoft Windows 3.1 DLL    [MS Windows only]
! #	mswinprn  Microsoft Windows 3.0, 3.1 printer   [MS Windows only]
  #   OS/2:
  # *	os2pm	OS/2 Presentation Manager   [OS/2 only]
  # *	os2dll	OS/2 DLL bitmap             [OS/2 only]
--- 45,52 ----
  #   MS Windows:
  #	mswin	Microsoft Windows 3.0, 3.1   [MS Windows only]
  #	mswindll  Microsoft Windows 3.1 DLL    [MS Windows only]
! #	mswinprn  Microsoft Windows 3.0, 3.1 DDB printer   [MS Windows only]
! #	mswinpr2  Microsoft Windows 3.0, 3.1 DIB printer [MS Windows only]
  #   OS/2:
  # *	os2pm	OS/2 Presentation Manager   [OS/2 only]
  # *	os2dll	OS/2 DLL bitmap             [OS/2 only]
***************
*** 399,411 ****
  mswindll.dev: $(mswindll_)
  	$(SETDEV) mswindll $(mswindll_)
  
! ### -------------------- The MS-Windows 3.n printer --------------------- ###
  
  mswinprn_=gdevwprn.$(OBJ) gdevmsxf.$(OBJ)
  mswinprn.dev: $(mswinprn_)
  	$(SETDEV) mswinprn $(mswinprn_)
  
  gdevwprn.$(OBJ): gdevwprn.c $(gdevmswn_h) $(gp_h)
  
  ### ------------------ OS/2 Presentation Manager device ----------------- ###
  
--- 400,420 ----
  mswindll.dev: $(mswindll_)
  	$(SETDEV) mswindll $(mswindll_)
  
! ### -------------------- The MS-Windows DDB 3.n printer ----------------- ###
  
  mswinprn_=gdevwprn.$(OBJ) gdevmsxf.$(OBJ)
  mswinprn.dev: $(mswinprn_)
  	$(SETDEV) mswinprn $(mswinprn_)
  
  gdevwprn.$(OBJ): gdevwprn.c $(gdevmswn_h) $(gp_h)
+ 
+ ### -------------------- The MS-Windows DIB 3.n printer ----------------- ###
+ 
+ mswinpr2_=gdevwpr2.$(OBJ) gdevprn.$(OBJ)
+ mswinpr2.dev: $(mswinpr2_)
+ 	$(SETDEV) mswinpr2 $(mswinpr2_)
+ 
+ gdevwpr2.$(OBJ): gdevwpr2.c $(gdevmswn_h) $(gp_h)
  
  ### ------------------ OS/2 Presentation Manager device ----------------- ###
  
diff -cr ./gdevdjet.c ../gdevdjet.c
*** ./gdevdjet.c	Thu Feb 09 14:43:42 1995
--- ../gdevdjet.c	Fri Apr 28 07:32:08 1995
***************
*** 285,296 ****
  /* hpjet_close is only here to eject odd numbered pages in duplex mode. */
  private int
  hpjet_close(gx_device *pdev)
! {	if ( pdev->Duplex_set >= 0 && pdev->Duplex )
! 	  {	gdev_prn_open_printer(pdev, 1);
! 		fputs("\033&l0H", ppdev->file) ;
! 		return gdev_prn_close_printer(pdev);
! 	  }
! 	return 0;
  }
  
  #undef ppdev
--- 285,295 ----
  /* hpjet_close is only here to eject odd numbered pages in duplex mode. */
  private int
  hpjet_close(gx_device *pdev)
! {       if ( pdev->Duplex_set >= 0 && pdev->Duplex )
!           {     gdev_prn_open_printer(pdev, 1);
!                 fputs("\033&l0H", ppdev->file) ;
!           }
!         return gdev_prn_close(pdev);
  }
  
  #undef ppdev
diff -cr ./gdevlbp8.c ../gdevlbp8.c
*** ./gdevlbp8.c	Thu Apr 27 19:20:48 1995
--- ../gdevlbp8.c	Thu Apr 27 19:25:44 1995
***************
*** 58,65 ****
    CSI, '7', ' ', 'I',	/* select unit size (300dpi)*/
  };
  
! static const char lbp8_end[] = {
! };
  
  static const char lips3_init[] = {
    ESC, '<', /* soft reset */
--- 58,64 ----
    CSI, '7', ' ', 'I',	/* select unit size (300dpi)*/
  };
  
! static const char *lbp8_end = NULL;
  
  static const char lips3_init[] = {
    ESC, '<', /* soft reset */
***************
*** 137,143 ****
  	fprintf(prn_stream, "%c=", ESC);
  
  	/* terminate */
! 	fwrite(end, end_size, 1, prn_stream);
  
  	return 0;
  }
--- 136,143 ----
  	fprintf(prn_stream, "%c=", ESC);
  
  	/* terminate */
! 	if (end != NULL)
! 	    fwrite(end, end_size, 1, prn_stream);
  
  	return 0;
  }
diff -cr ./gdevwpr2.c ../gdevwpr2.c
*** ./gdevwpr2.c	Sat Apr 29 12:13:46 1995
--- ../gdevwpr2.c	Sat Apr 29 09:07:00 1995
***************
*** 0 ****
--- 1,439 ----
+ /* Copyright (C) 1989, 1995 Aladdin Enterprises.  All rights reserved.
+   
+   This file is part of Aladdin Ghostscript.
+   
+   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
+   or distributor accepts any responsibility for the consequences of using it,
+   or for whether it serves any particular purpose or works at all, unless he
+   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
+   License (the "License") for full details.
+   
+   Every copy of Aladdin Ghostscript must include a copy of the License,
+   normally in a plain ASCII text file named PUBLIC.  The License grants you
+   the right to copy, modify and redistribute Aladdin Ghostscript, but only
+   under certain conditions described in the License.  Among other things, the
+   License requires that the copyright notice and this notice be preserved on
+   all copies.
+ */
+ 
+ /* gdevwpr2.c */
+ /*
+  * Microsoft Windows 3.n printer driver for Ghostscript.
+  * Original version by Russell Lang and
+  * L. Peter Deutsch, Aladdin Enterprises.
+  * Modified by rjl 1995-03-29 to use BMP printer code
+  */
+ #include "gdevprn.h"
+ #include "gdevpccm.h"
+ 
+ #include "windows_.h"
+ #include <shellapi.h>
+ #include "gp_mswin.h"
+ 
+ #include "gp.h"
+ #include "commdlg.h"
+ 
+ 
+ /* Make sure we cast to the correct structure type. */
+ typedef struct gx_device_win_pr2_s gx_device_win_pr2;
+ #undef wdev
+ #define wdev ((gx_device_win_pr2 *)dev)
+ 
+ /* Device procedures */
+ 
+ /* See gxdevice.h for the definitions of the procedures. */
+ private dev_proc_open_device(win_pr2_open);
+ private dev_proc_close_device(win_pr2_close);
+ private dev_proc_print_page(win_pr2_print_page);
+ private dev_proc_map_rgb_color(win_pr2_map_rgb_color);
+ private dev_proc_map_color_rgb(win_pr2_map_color_rgb);
+ private dev_proc_put_params(win_pr2_put_params);
+ 
+ private void win_pr2_set_bpp(gx_device *dev, int depth);
+ 
+ private gx_device_procs win_pr2_procs =
+   prn_color_params_procs(win_pr2_open, gdev_prn_output_page, win_pr2_close,
+    win_pr2_map_rgb_color, win_pr2_map_color_rgb, 
+    gdev_prn_get_params, win_pr2_put_params);
+ 
+ 
+ /* The device descriptor */
+ typedef struct gx_device_win_pr2_s gx_device_win_pr2;
+ struct gx_device_win_pr2_s {
+ 	gx_device_common;
+ 	gx_prn_device_common;
+ 	HDC hdcprn;
+ 	DLGPROC lpfnAbortProc;
+ 	DLGPROC lpfnCancelProc;
+ };
+ 
+ gx_device_win_pr2 far_data gs_mswinpr2_device = {
+   prn_device_std_body(gx_device_printer, win_pr2_procs, "mswinpr2",
+   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 72, 72,
+   0, 0, 0, 0,
+   0, win_pr2_print_page), /* depth = 0 */
+   0,	/* hdcprn */
+   NULL	/* lpfnAbortProc */
+ };
+ 
+ /* Open the win_pr2 driver */
+ private int
+ win_pr2_open(gx_device *dev)
+ {	int code;
+ 	int depth;
+ 	PRINTDLG pd;
+ 	POINT offset;
+ 	POINT size;
+ 	float m[4];
+ 	FILE *pfile;
+ 
+ 	if (hDlgModeless) {
+ 	    /* device cannot opened twice since only one hDlgModeless */
+ 	    return gs_error_limitcheck;
+ 	}
+ 
+ 	/* get a HDC for the printer */
+ 	memset(&pd, 0, sizeof(PRINTDLG));
+ 	pd.lStructSize = sizeof(PRINTDLG);
+ 	pd.hwndOwner = hwndtext;
+ 	pd.Flags = PD_PRINTSETUP | PD_RETURNDC;
+ 	if (!PrintDlg(&pd)) {
+ 	    /* device not opened - exit ghostscript */
+ 	    return gs_error_limitcheck;
+ 	}
+ 	GlobalFree(pd.hDevMode);
+ 	GlobalFree(pd.hDevNames);
+ 	pd.hDevMode = pd.hDevNames = NULL;
+ 	wdev->hdcprn = pd.hDC;
+ 	if (!(GetDeviceCaps(wdev->hdcprn, RASTERCAPS) != RC_BITBLT)) {
+ 	    DeleteDC(wdev->hdcprn);
+ 	    return gs_error_limitcheck;
+ 	}
+ 
+ 	/* initialise printer, install abort proc */
+ #ifdef __WIN32__
+ 	wdev->lpfnAbortProc = (DLGPROC)AbortProc;
+ #else
+ #ifdef __DLL__
+ 	wdev->lpfnAbortProc = (DLGPROC)GetProcAddress(phInstance, "AbortProc");
+ #else
+ 	wdev->lpfnAbortProc = (DLGPROC)MakeProcInstance((FARPROC)AbortProc,phInstance);
+ #endif
+ #endif
+ 	Escape(wdev->hdcprn,SETABORTPROC,0,(LPSTR)wdev->lpfnAbortProc,NULL);  
+ 	if (Escape(wdev->hdcprn, STARTDOC, lstrlen(szAppName), szAppName, NULL) <= 0) {
+ 	    FreeProcInstance((FARPROC)wdev->lpfnAbortProc);
+ 	    DeleteDC(wdev->hdcprn);
+ 	    return gs_error_limitcheck;
+ 	}
+ 
+ 	dev->x_pixels_per_inch = GetDeviceCaps(wdev->hdcprn, LOGPIXELSX);
+ 	dev->y_pixels_per_inch = GetDeviceCaps(wdev->hdcprn, LOGPIXELSY);
+ 	Escape(wdev->hdcprn, GETPHYSPAGESIZE, NULL, NULL, (LPPOINT)&size);
+ 	dev->width = size.x;
+ 	dev->height = size.y;
+ 	Escape(wdev->hdcprn, GETPRINTINGOFFSET, NULL, NULL, (LPPOINT)&offset);
+ 	/* m[] gives margins in inches */
+ 	m[0] /*left*/ = offset.x / dev->x_pixels_per_inch;
+ 	m[3] /*top*/ = offset.y / dev->y_pixels_per_inch;
+ 	m[2] /*right*/ =
+ 		(size.x - offset.x - GetDeviceCaps(wdev->hdcprn, HORZRES))
+ 		 / dev->x_pixels_per_inch;
+ 	m[1] /*bottom*/ =
+ 		(size.y - offset.y - GetDeviceCaps(wdev->hdcprn, VERTRES))
+ 		 / dev->y_pixels_per_inch
+ 		+ 0.15;  /* hack to add a bit more margin for deskjet printer */
+ 	gx_device_set_margins(dev, m, true);
+ 
+ 	depth = dev->color_info.depth;
+ 	if (depth == 0) {
+ 	    /* Set parameters that were unknown before opening device */
+ 	    /* Find out if the device supports color */
+ 	    /* We recognize 1, 3, 8 and 24 bit color devices */
+ 	    depth = GetDeviceCaps(wdev->hdcprn,PLANES) * GetDeviceCaps(wdev->hdcprn,BITSPIXEL);
+ 	}
+ 	win_pr2_set_bpp(dev, depth);
+ 
+ 	/* gdev_prn_open opens a temporary file which we don't want */
+ 	/* so we specify the name now so we can delete it later */
+ 	pfile = gp_open_scratch_file(gp_scratch_file_name_prefix, 
+ 		wdev->fname, "wb");
+ 	fclose(pfile);
+ 	code = gdev_prn_open(dev);
+ 
+ 	/* inform user of progress with dialog box and allow cancel */
+ #ifdef __WIN32__
+ 	wdev->lpfnCancelProc = (DLGPROC)CancelDlgProc;
+ #else
+ #ifdef __DLL__
+ 	wdev->lpfnCancelProc = (DLGPROC)GetProcAddress(phInstance, "CancelDlgProc");
+ #else
+ 	wdev->lpfnCancelProc = (DLGPROC)MakeProcInstance((FARPROC)CancelDlgProc, phInstance);
+ #endif
+ #endif
+ 	hDlgModeless = CreateDialog(phInstance, "CancelDlgBox", hwndtext, wdev->lpfnCancelProc);
+ 	ShowWindow(hDlgModeless, SW_HIDE);
+ 
+ 	return code;
+ };
+ 
+ /* Close the win_pr2 driver */
+ private int
+ win_pr2_close(gx_device *dev)
+ {	int code;
+ 	int aborted = FALSE;
+ 	/* Free resources */
+ 
+ 	if (!hDlgModeless)
+ 	    aborted = TRUE;
+ 	DestroyWindow(hDlgModeless);
+ 	hDlgModeless = 0;
+ #ifndef __DLL__
+ 	FreeProcInstance((FARPROC)wdev->lpfnCancelProc);
+ #endif
+ 
+ 	if (aborted)
+ 	    Escape(wdev->hdcprn,ABORTDOC,0,NULL,NULL);
+ 	else
+ 	    Escape(wdev->hdcprn,ENDDOC,0,NULL,NULL);
+ 
+ 	FreeProcInstance((FARPROC)wdev->lpfnAbortProc);
+ 	DeleteDC(wdev->hdcprn);
+ 	code = gdev_prn_close(dev);
+ 	/* delete unwanted temporary file */
+ 	unlink(wdev->fname);
+ 	return code;
+ }
+ 
+ 
+ /* ------ Internal routines ------ */
+ 
+ #undef wdev
+ #define wdev ((gx_device_win_pr2 *)pdev)
+ 
+ /************************************************/
+ 
+ 
+ /* ------ Private definitions ------ */
+ 
+ 
+ /* new win_pr2_print_page routine */
+ 
+ /* Write BMP header to memory, then send bitmap to printer */
+ /* one scan line at a time */
+ private int
+ win_pr2_print_page(gx_device_printer *pdev, FILE *file)
+ {	int raster = gdev_prn_raster(pdev);
+ 	/* BMP scan lines are padded to 32 bits. */
+ 	ulong bmp_raster = raster + (-raster & 3);
+ 	int height = pdev->height;
+ 	int depth = pdev->color_info.depth;
+ 	byte *row = (byte *)gs_malloc(bmp_raster, 1, "bmp file buffer");
+ 	int y;
+ 	int code = 0;			/* return code */
+ 	MSG msg;
+ 	char dlgtext[32];
+ 
+ 	struct bmi_s {
+ 		BITMAPINFOHEADER h;
+ 		RGBQUAD pal[256];
+ 	} bmi;
+ 
+ 	if ( row == 0 )			/* can't allocate row buffer */
+ 		return_error(gs_error_VMerror);
+ 
+ 	/* Write the info header. */
+ 
+ 	bmi.h.biSize = sizeof(bmi.h);
+ 	bmi.h.biWidth = pdev->width;  /* wdev->mdev.width; */
+ 	bmi.h.biHeight = height;
+ 	bmi.h.biPlanes = 1;
+ 	bmi.h.biBitCount = pdev->color_info.depth;
+ 	bmi.h.biCompression = 0;
+ 	bmi.h.biSizeImage = 0;			/* default */
+ 	bmi.h.biXPelsPerMeter = 0;		/* default */
+ 	bmi.h.biYPelsPerMeter = 0;		/* default */
+ 
+ 	/* Write the palette. */
+ 
+ 	if ( depth <= 8 )
+ 	{	int i;
+ 		gx_color_value rgb[3];
+ 		LPRGBQUAD pq;
+ 		bmi.h.biClrUsed = 1 << depth;
+ 		bmi.h.biClrImportant = 1 << depth;
+ 		for ( i = 0; i != 1 << depth; i++ )
+ 		{	(*dev_proc(pdev, map_color_rgb))((gx_device *)pdev,
+ 				(gx_color_index)i, rgb);
+ 			pq = &bmi.pal[i];
+ 			pq->rgbRed   = gx_color_value_to_byte(rgb[0]);
+ 			pq->rgbGreen = gx_color_value_to_byte(rgb[1]);
+ 			pq->rgbBlue  = gx_color_value_to_byte(rgb[2]);
+ 			pq->rgbReserved = 0;
+ 		}
+ 	}
+ 	else {
+ 		bmi.h.biClrUsed = 0;
+ 		bmi.h.biClrImportant = 0;
+ 	}
+ 
+ 	sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount)+1);
+ 	SetWindowText(GetDlgItem(hDlgModeless, CANCEL_PRINTING), dlgtext);
+ 	ShowWindow(hDlgModeless, SW_SHOW);
+ 
+ 	/* write the bits */
+ 	for ( y = 0; y < height; y++) {
+ 	    gdev_prn_copy_scan_lines(pdev, y, row, raster);
+ 	    /* write top first, since most printers output this way, and */
+             /* so less buffering is required by printer and printer driver */
+ 	    SetDIBitsToDevice(wdev->hdcprn, 0, y, pdev->width, 1,
+ 		0, 0, 0, 1,
+ 		row,
+ 		(BITMAPINFO FAR *)&bmi, DIB_RGB_COLORS);
+ 	    if ((y & 15) == 0) {
+ 	        /* inform user of progress */
+ 		sprintf(dlgtext, "%d%% done", (int)(y * 100L / height));
+ 		SetWindowText(GetDlgItem(hDlgModeless, CANCEL_PCDONE), dlgtext);
+ 		/* process message loop */
+ 		while (PeekMessage(&msg, hDlgModeless, 0, 0, PM_REMOVE)) {
+ 		    if ((hDlgModeless == 0) || !IsDialogMessage(hDlgModeless, &msg)) {
+ 			TranslateMessage(&msg);
+ 			DispatchMessage(&msg);
+ 		    }
+ 		}
+ 	    }
+ 	    if (hDlgModeless == 0) {
+ 	        /* user pressed cancel button */
+ 		break;
+ 	    }
+ 	}
+ 
+ 	if (hDlgModeless == 0)
+ 	    code = gs_error_unknownerror;
+ 	else {
+ 	    /* push out the page */
+ 	    SetWindowText(GetDlgItem(hDlgModeless, CANCEL_PCDONE), "Ejecting page...");
+ 	    Escape(wdev->hdcprn,NEWFRAME,0,NULL,NULL);
+ 	    ShowWindow(hDlgModeless, SW_HIDE);
+ 	}
+ 
+ bmp_done:
+ 	gs_free((char *)row, bmp_raster, 1, "bmp file buffer");
+ 
+ 	return code;
+ }
+ 
+ /* combined color mappers */
+ 
+ /* 24-bit color mappers (taken from gdevmem2.c). */
+ /* Note that Windows expects RGB values in the order B,G,R. */
+ 
+ /* Map a r-g-b color to a color index. */
+ private gx_color_index
+ win_pr2_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g,
+   gx_color_value b)
+ {
+     switch(dev->color_info.depth) {
+       case 1:
+ 	return gdev_prn_map_rgb_color(dev, r, g, b);
+       case 4:
+ 	/* use only 8 colors */
+ 	return  (r > (gx_max_color_value / 2 + 1) ? 4 : 0) +
+ 	         (g > (gx_max_color_value / 2 + 1) ? 2 : 0) +
+ 	         (b > (gx_max_color_value / 2 + 1) ? 1 : 0) ;
+       case 8:
+ 	return pc_8bit_map_rgb_color(dev, r, g, b);
+       case 24:
+ 	return gx_color_value_to_byte(r) +
+ 	       ((uint)gx_color_value_to_byte(g) << 8) +
+ 	       ((ulong)gx_color_value_to_byte(b) << 16);
+     }
+     return 0; /* error */
+ }
+ 
+ /* Map a color index to a r-g-b color. */
+ private int
+ win_pr2_map_color_rgb(gx_device *dev, gx_color_index color,
+   gx_color_value prgb[3])
+ {
+     switch(dev->color_info.depth) {
+       case 1:
+ 	gdev_prn_map_color_rgb(dev, color, prgb);
+ 	break;
+       case 4:
+ 	/* use only 8 colors */
+ 	prgb[0] = (color & 4) ? gx_max_color_value : 0;
+ 	prgb[1] = (color & 2) ? gx_max_color_value : 0;
+ 	prgb[2] = (color & 1) ? gx_max_color_value : 0;
+ 	break;
+       case 8:
+ 	pc_8bit_map_color_rgb(dev, color, prgb);
+ 	break;
+       case 24:
+ 	prgb[2] = gx_color_value_from_byte(color >> 16);
+ 	prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
+ 	prgb[0] = gx_color_value_from_byte(color & 0xff);
+ 	break;
+     }
+     return 0;
+ }
+ 
+ void
+ win_pr2_set_bpp(gx_device *dev, int depth)
+ {
+ 	if (depth > 8) {
+ 	    static const gx_device_color_info win_pr2_24color = dci_std_color(24);
+ 	    dev->color_info = win_pr2_24color;
+ 	}
+ 	else if ( depth >= 8 ) {
+ 	    /* 8-bit (SuperVGA-style) color. */
+ 	    /* (Uses a fixed palette of 3,3,2 bits.) */
+ 	    static const gx_device_color_info win_pr2_8color = dci_pc_8bit;
+ 	    dev->color_info = win_pr2_8color;
+ 	}
+ 	else if ( depth >= 3) {
+ 	    /* 3 plane printer */
+ 	    /* suitable for impact dot matrix CMYK printers */
+ 	    /* create 4-bit bitmap, but only use 8 colors */
+ 	    static const gx_device_color_info win_pr2_4color = {3, 4, 1, 1, 2, 2};
+ 	    dev->color_info = win_pr2_4color;
+ 	}
+ 	else {   /* default is black_and_white */
+ 	    static const gx_device_color_info win_pr2_1color = dci_std_color(1);
+ 	    dev->color_info = win_pr2_1color;
+ 	}
+ }
+ 
+ 
+ /* We implement this ourselves so that we can change BitsPerPixel */
+ /* before the device is opened */
+ int
+ win_pr2_put_params(gx_device *dev, gs_param_list *plist)
+ {	int ecode = 0, code;
+ 	int old_bpp = dev->color_info.depth;
+ 	int bpp = old_bpp;
+ 
+ 	switch ( code = param_read_int(plist, "BitsPerPixel", &bpp) )
+ 	{
+ 	case 0:
+ 		if ( dev->is_open )
+ 		  ecode = gs_error_rangecheck;
+ 		else
+ 		  {	/* change dev->color_info is valid before device is opened */
+ 			win_pr2_set_bpp(dev, bpp);
+ 			break;
+ 		  }
+ 		goto bppe;
+ 	default:
+ 		ecode = code;
+ bppe:		param_signal_error(plist, "BitsPerPixel", ecode);
+ 	case 1:
+ 		break;
+ 	}
+ 
+ 	if ( ecode >= 0 )
+ 		ecode = gdev_prn_put_params(dev, plist);
+ 	return ecode;
+ }
+ 
+ 
diff -cr ./gp_mswin.c ../gp_mswin.c
*** ./gp_mswin.c	Sat Feb 04 20:30:28 1995
--- ../gp_mswin.c	Wed Mar 29 07:48:28 1995
***************
*** 348,375 ****
  	unlink(win_prntmp);
  }
  
! #ifndef __WIN32__
! 
! /* Windows does not provide API's in the SDK for writing directly to a */
! /* printer.  Instead you are supposed to use the Windows printer drivers. */
! /* Ghostscript has its own printer drivers, so we need to use some API's */
! /* that are documented only in the Device Driver Adaptation Guide */
! /* that comes with the DDK.  Prototypes taken from DDK <print.h> */
! DECLARE_HANDLE(HPJOB);
! 
! HPJOB	WINAPI OpenJob(LPSTR, LPSTR, HPJOB);
! int	WINAPI StartSpoolPage(HPJOB);
! int	WINAPI EndSpoolPage(HPJOB);
! int	WINAPI WriteSpool(HPJOB, LPSTR, int);
! int	WINAPI CloseJob(HPJOB);
! int	WINAPI DeleteJob(HPJOB, int);
! int	WINAPI WriteDialog(HPJOB, LPSTR, int);
! int	WINAPI DeleteSpoolPage(HPJOB);
! 
! #endif		/* WIN32 */
  
  HWND hDlgModeless;
  
  /* Modeless dialog box - Cancel printing */
  BOOL CALLBACK _export
  CancelDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
--- 348,371 ----
  	unlink(win_prntmp);
  }
  
! /* Printer abort procedure and progress/cancel dialog box */
! /* Used by Win32 and mswinprn device */
  
  HWND hDlgModeless;
  
+ BOOL CALLBACK _export
+ PrintAbortProc(HDC hdcPrn, int code)
+ {
+     MSG msg;
+     while (hDlgModeless && PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
+ 	if (hDlgModeless || !IsDialogMessage(hDlgModeless,&msg)) {
+             TranslateMessage(&msg);
+             DispatchMessage(&msg);
+ 	}
+     }
+     return(hDlgModeless!=0);
+ }
+ 
  /* Modeless dialog box - Cancel printing */
  BOOL CALLBACK _export
  CancelDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
***************
*** 390,395 ****
--- 386,411 ----
      return FALSE;
  }
  
+ #ifndef __WIN32__
+ 
+ /* Windows does not provide API's in the SDK for writing directly to a */
+ /* printer.  Instead you are supposed to use the Windows printer drivers. */
+ /* Ghostscript has its own printer drivers, so we need to use some API's */
+ /* that are documented only in the Device Driver Adaptation Guide */
+ /* that comes with the DDK.  Prototypes taken from DDK <print.h> */
+ DECLARE_HANDLE(HPJOB);
+ 
+ HPJOB	WINAPI OpenJob(LPSTR, LPSTR, HPJOB);
+ int	WINAPI StartSpoolPage(HPJOB);
+ int	WINAPI EndSpoolPage(HPJOB);
+ int	WINAPI WriteSpool(HPJOB, LPSTR, int);
+ int	WINAPI CloseJob(HPJOB);
+ int	WINAPI DeleteJob(HPJOB, int);
+ int	WINAPI WriteDialog(HPJOB, LPSTR, int);
+ int	WINAPI DeleteSpoolPage(HPJOB);
+ 
+ #endif		/* WIN32 */
+ 
  /* Dialog box to select printer port */
  BOOL CALLBACK _export
  SpoolDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
***************
*** 431,448 ****
  
  /* Win32s can't get access to OpenJob etc., so we try to sneak the */
  /* data through the Windows printer driver unchanged */
- BOOL CALLBACK _export
- PrintAbortProc(HDC hdcPrn, int code)
- {
-     MSG msg;
-     while (hDlgModeless && PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
- 	if (hDlgModeless || !IsDialogMessage(hDlgModeless,&msg)) {
-             TranslateMessage(&msg);
-             DispatchMessage(&msg);
- 	}
-     }
-     return(hDlgModeless!=0);
- }
  
  /* Print File */
  private int
--- 447,452 ----
***************
*** 541,549 ****
--- 545,559 ----
  	if ( (strlen(pmport)==0) || (strcmp(pmport, "PRN")==0) ) {
  	    GetProfileString("ports", NULL, "", buffer, PRINT_BUF_SIZE);
  	    /* select a port */
+ #ifdef __DLL__
+ 	    lpfnSpoolProc = (DLGPROC)GetProcAddress(phInstance, "SpoolDlgProc");
+ #else
  	    lpfnSpoolProc = (DLGPROC)MakeProcInstance((FARPROC)SpoolDlgProc, phInstance);
+ #endif
  	    port = DialogBoxParam(phInstance, "SpoolDlgBox", hwndtext, lpfnSpoolProc, (LPARAM)buffer);
+ #ifndef __DLL__
  	    FreeProcInstance((FARPROC)lpfnSpoolProc);
+ #endif
  	    if (!port) {
  	        free(buffer);
  	        return FALSE;
***************
*** 579,585 ****
--- 589,599 ----
  	if (StartSpoolPage(hJob) < 0)
  	    error = TRUE;
  
+ #ifdef __DLL__
+ 	lpfnCancelProc = (DLGPROC)GetProcAddress(phInstance, "CancelDlgProc");
+ #else
  	lpfnCancelProc = (DLGPROC)MakeProcInstance((FARPROC)CancelDlgProc, phInstance);
+ #endif
  	hDlgModeless = CreateDialog(phInstance, "CancelDlgBox", hwndtext, lpfnCancelProc);
  	ldone = 0;
  
***************
*** 604,610 ****
--- 618,626 ----
  	    error=TRUE;
  	DestroyWindow(hDlgModeless);
  	hDlgModeless = 0;
+ #ifndef __DLL__
  	FreeProcInstance((FARPROC)lpfnCancelProc);
+ #endif
  	EndSpoolPage(hJob);
  	if (error)
  	    DeleteJob(hJob, 0);
diff -cr ./gp_mswin.h ../gp_mswin.h
*** ./gp_mswin.h	Wed Nov 02 14:00:08 1994
--- ../gp_mswin.h	Mon Mar 27 21:59:56 1995
***************
*** 24,29 ****
--- 24,30 ----
  #define IMAGE_ICON	51
  #define SPOOL_PORT	100
  #define CANCEL_PCDONE	101
+ #define CANCEL_PRINTING	102
  
  #ifndef RC_INVOKED		/* NOTA BENE */
  
***************
*** 40,51 ****
--- 41,54 ----
  #endif
  
  extern HWND hwndtext;
+ extern HWND hDlgModeless;
  extern HINSTANCE phInstance;
  extern const LPSTR szAppName;
  extern const LPSTR szImgName;
  extern BOOL is_win31;
  extern BOOL is_winnt;
  extern BOOL CALLBACK _export AbortProc(HDC, int);
+ extern BOOL CALLBACK _export CancelDlgProc(HWND, UINT, WPARAM, LPARAM);
  /* imitation pipes */
  extern HGLOBAL pipe_hglobal;
  extern LPBYTE pipe_lpbyte;
diff -cr ./gswin.rc ../gswin.rc
*** ./gswin.rc	Wed Jul 27 15:40:24 1994
--- ../gswin.rc	Mon Mar 27 21:48:04 1995
***************
*** 16,22 ****
  CancelDlgBox DIALOG 32, 40, 120, 48
  STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
  BEGIN
! 	CTEXT "Printing", -1, 8, 4, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
  	CTEXT "", CANCEL_PCDONE, 8, 16, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
  	CONTROL "&Cancel", IDCANCEL, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 44, 30, 32, 14
  END
--- 16,22 ----
  CancelDlgBox DIALOG 32, 40, 120, 48
  STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
  BEGIN
! 	CTEXT "Printing", CANCEL_PRINTING, 8, 4, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
  	CTEXT "", CANCEL_PCDONE, 8, 16, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
  	CONTROL "&Cancel", IDCANCEL, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 44, 30, 32, 14
  END
diff -cr ./gswin32.rc ../gswin32.rc
*** ./gswin32.rc	Wed Jul 27 15:40:24 1994
--- ../gswin32.rc	Mon Mar 27 21:48:04 1995
***************
*** 16,22 ****
  CancelDlgBox DIALOG 32, 40, 120, 48
  STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
  BEGIN
! 	CTEXT "Printing", -1, 8, 4, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
  	CTEXT "", CANCEL_PCDONE, 8, 16, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
  	CONTROL "&Cancel", IDCANCEL, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 44, 30, 32, 14
  END
--- 16,22 ----
  CancelDlgBox DIALOG 32, 40, 120, 48
  STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
  BEGIN
! 	CTEXT "Printing", CANCEL_PRINTING, 8, 4, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
  	CTEXT "", CANCEL_PCDONE, 8, 16, 104, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
  	CONTROL "&Cancel", IDCANCEL, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 44, 30, 32, 14
  END
diff -cr ./os2.mak ../os2.mak
*** ./os2.mak	Sat Mar 18 16:29:40 1995
--- ../os2.mak	Sat Apr 29 12:17:30 1995
***************
*** 280,286 ****
  CDLL=
  !endif
  
! GENOPT=$(CP) $(CD) $(CGDB) $(CDLL)
  
  CCFLAGS0=$(GENOPT) $(PLATOPT)
  CCFLAGS=$(CCFLAGS0) 
--- 280,286 ----
  CDLL=
  !endif
  
! GENOPT=$(CP) $(CD) $(CGDB) $(CDLL) $(CO)
  
  CCFLAGS0=$(GENOPT) $(PLATOPT)
  CCFLAGS=$(CCFLAGS0) 
***************
*** 299,305 ****
  # Choose the language feature(s) to include.  See gs.mak for details.
  # Since we have a large address space, we include some optional features.
  
! FEATURE_DEVS=level2.dev dps.dev
  
  # Choose the device(s) to include.  See devs.mak for details.
  
--- 299,305 ----
  # Choose the language feature(s) to include.  See gs.mak for details.
  # Since we have a large address space, we include some optional features.
  
! FEATURE_DEVS=level2.dev dps.dev pdf.dev
  
  # Choose the device(s) to include.  See devs.mak for details.
  
***************
*** 308,317 ****
  !else
  DEVICE_DEVS=os2pm.dev
  !endif
  DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
  DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
  DEVICE_DEVS5=djet500c.dev declj250.dev lj250.dev jetp3852.dev r4081.dev t4693d2.dev t4693d4.dev t4693d8.dev tek4696.dev lbp8.dev
! DEVICE_DEVS6=epson.dev eps9high.dev eps9mid.dev epsonc.dev ibmpro.dev st800.dev bj10e.dev bj200.dev m8510.dev necp6.dev
  DEVICE_DEVS7=dfaxhigh.dev dfaxlow.dev
  DEVICE_DEVS8=bmpmono.dev bmp16.dev bmp256.dev bmp16m.dev pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev
  DEVICE_DEVS9=psmono.dev bit.dev bitrgb.dev bitcmyk.dev
--- 308,318 ----
  !else
  DEVICE_DEVS=os2pm.dev
  !endif
+ DEVICE_DEVS2=epson.dev eps9high.dev eps9mid.dev epsonc.dev ibmpro.dev
  DEVICE_DEVS3=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev ljet4.dev
  DEVICE_DEVS4=cdeskjet.dev cdjcolor.dev cdjmono.dev cdj550.dev pj.dev pjxl.dev pjxl300.dev
  DEVICE_DEVS5=djet500c.dev declj250.dev lj250.dev jetp3852.dev r4081.dev t4693d2.dev t4693d4.dev t4693d8.dev tek4696.dev lbp8.dev
! DEVICE_DEVS6=st800.dev stcolor.dev bj10e.dev bj200.dev m8510.dev necp6.dev
  DEVICE_DEVS7=dfaxhigh.dev dfaxlow.dev
  DEVICE_DEVS8=bmpmono.dev bmp16.dev bmp256.dev bmp16m.dev pcxmono.dev pcxgray.dev pcx16.dev pcx256.dev pcx24b.dev
  DEVICE_DEVS9=psmono.dev bit.dev bitrgb.dev bitcmyk.dev
***************
*** 388,399 ****
  # PM driver program
  
  gspmdrv.o: gspmdrv.c gspmdrv.h
! 	$(COMPDIR)\gcc $(CGDB) -c $*.c
  
  gspmdrv.res: gspmdrv.rc gspmdrv.h gspmdrv.ico
  	rc -i $(COMPBASE)\include -r $*.rc
  
  gspmdrv.exe: gspmdrv.o gspmdrv.res gspmdrv.def
! 	$(COMPDIR)\gcc $(CGDB) -o $* $*.o
  	$(COMPDIR)\emxbind -p -r$*.res -d$*.def $(COMPDIR)\emxl.exe $* $*.exe
  	del $*
--- 389,400 ----
  # PM driver program
  
  gspmdrv.o: gspmdrv.c gspmdrv.h
! 	$(COMPDIR)\gcc $(CGDB) $(CO) -c $*.c
  
  gspmdrv.res: gspmdrv.rc gspmdrv.h gspmdrv.ico
  	rc -i $(COMPBASE)\include -r $*.rc
  
  gspmdrv.exe: gspmdrv.o gspmdrv.res gspmdrv.def
! 	$(COMPDIR)\gcc $(CGDB) $(CO) -o $* $*.o
  	$(COMPDIR)\emxbind -p -r$*.res -d$*.def $(COMPDIR)\emxl.exe $* $*.exe
  	del $*
