13ff48bf5SDavid du Colombier /* Copyright (C) 1989, 2000 Aladdin Enterprises. 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: gdevwpr2.c,v 1.18 2004/08/05 17:02:36 stefan Exp $ */
187dd7cddfSDavid du Colombier /*
197dd7cddfSDavid du Colombier * Microsoft Windows 3.n printer driver for Ghostscript.
207dd7cddfSDavid du Colombier * Original version by Russell Lang and
217dd7cddfSDavid du Colombier * L. Peter Deutsch, Aladdin Enterprises.
227dd7cddfSDavid du Colombier * Modified by rjl 1995-03-29 to use BMP printer code
237dd7cddfSDavid du Colombier * Modified by Pierre Arnaud 1999-02-18 (see description below)
247dd7cddfSDavid du Colombier * Modified by lpd 1999-04-03 for compatibility with Borland C++ 4.5.
257dd7cddfSDavid du Colombier * Modified by Pierre Arnaud 1999-10-03 (accept b&w printing on color printers).
267dd7cddfSDavid du Colombier * Modified by Pierre Arnaud 1999-11-20 (accept lower resolution)
277dd7cddfSDavid du Colombier * Bug fixed by Pierre Arnaud 2000-03-09 (win_pr2_put_params error when is_open)
283ff48bf5SDavid du Colombier * Bug fixed by Pierre Arnaud 2000-03-20 (win_pr2_set_bpp did not set anti_alias)
293ff48bf5SDavid du Colombier * Bug fixed by Pierre Arnaud 2000-03-22 (win_pr2_set_bpp depth was wrong)
303ff48bf5SDavid du Colombier * Modified by Pierre Arnaud 2000-12-12 (mainly added support for Tumble)
313ff48bf5SDavid du Colombier * Bug fixed by Pierre Arnaud 2000-12-18 (-dQueryUser now works from cmd line)
327dd7cddfSDavid du Colombier */
337dd7cddfSDavid du Colombier
347dd7cddfSDavid du Colombier /* This driver uses the printer default size and resolution and
357dd7cddfSDavid du Colombier * ignores page size and resolution set using -gWIDTHxHEIGHT and
367dd7cddfSDavid du Colombier * -rXxY. You must still set the correct PageSize to get the
377dd7cddfSDavid du Colombier * correct clipping path.
387dd7cddfSDavid du Colombier * The code in win_pr2_getdc() does try to set the printer page
397dd7cddfSDavid du Colombier * size from the PostScript PageSize, but it isn't working
407dd7cddfSDavid du Colombier * reliably at the moment.
417dd7cddfSDavid du Colombier *
427dd7cddfSDavid du Colombier * This driver doesn't work with some Windows printer drivers.
437dd7cddfSDavid du Colombier * The reason is unknown. All printers to which I have access
447dd7cddfSDavid du Colombier * work.
457dd7cddfSDavid du Colombier *
467dd7cddfSDavid du Colombier * rjl 1997-11-20
477dd7cddfSDavid du Colombier */
487dd7cddfSDavid du Colombier
493ff48bf5SDavid du Colombier /* Additions by Pierre Arnaud (Pierre.Arnaud@opac.ch)
507dd7cddfSDavid du Colombier *
517dd7cddfSDavid du Colombier * The driver has been extended in order to provide some run-time
527dd7cddfSDavid du Colombier * feed-back about the default Windows printer and to give the user
537dd7cddfSDavid du Colombier * the opportunity to select the printer's properties before the
547dd7cddfSDavid du Colombier * device gets opened (and any spooling starts).
557dd7cddfSDavid du Colombier *
567dd7cddfSDavid du Colombier * The driver returns an additional property named "UserSettings".
577dd7cddfSDavid du Colombier * This is a dictionary which contens are valid only after setting
587dd7cddfSDavid du Colombier * the QueryUser property (see below). The UserSettings dict contains
597dd7cddfSDavid du Colombier * the following keys:
607dd7cddfSDavid du Colombier *
617dd7cddfSDavid du Colombier * DocumentRange [begin end] (int array, can be set)
627dd7cddfSDavid du Colombier * Defines the range of pages in the document; [1 10] would
637dd7cddfSDavid du Colombier * describe a document starting at page 1 and ending at page 10.
647dd7cddfSDavid du Colombier *
657dd7cddfSDavid du Colombier * SelectedRange [begin end] (int array, can be set)
667dd7cddfSDavid du Colombier * Defines the pages the user wants to print.
677dd7cddfSDavid du Colombier *
687dd7cddfSDavid du Colombier * MediaSize [width height] (float array, read only)
697dd7cddfSDavid du Colombier * Current printer's media size.
707dd7cddfSDavid du Colombier *
717dd7cddfSDavid du Colombier * Copies n (integer, can be set)
727dd7cddfSDavid du Colombier * User selected number of copies.
737dd7cddfSDavid du Colombier *
747dd7cddfSDavid du Colombier * PrintCopies n (integer, read only)
757dd7cddfSDavid du Colombier * Number of copies which must be printed by Ghostscript itself.
767dd7cddfSDavid du Colombier * This is still experimental.
777dd7cddfSDavid du Colombier *
787dd7cddfSDavid du Colombier * DocumentName name (string, can be set)
797dd7cddfSDavid du Colombier * Name to be associated with the print job.
807dd7cddfSDavid du Colombier *
817dd7cddfSDavid du Colombier * UserChangedSettings (bool, read only)
827dd7cddfSDavid du Colombier * Set to 'true' if the last QueryUser operation succeeded.
837dd7cddfSDavid du Colombier *
847dd7cddfSDavid du Colombier * Paper n (integer, can be set)
857dd7cddfSDavid du Colombier * Windows paper selection (0 = automatic).
867dd7cddfSDavid du Colombier *
877dd7cddfSDavid du Colombier * Orient n (integer, can be set)
887dd7cddfSDavid du Colombier * Windows paper orientation (0 = automatic).
897dd7cddfSDavid du Colombier *
907dd7cddfSDavid du Colombier * Color n (integer, can be set)
917dd7cddfSDavid du Colombier * Windows color (0 = automatic, 1 = monochrome, 2 = color).
927dd7cddfSDavid du Colombier *
937dd7cddfSDavid du Colombier * MaxResolution n (integer, can be set)
947dd7cddfSDavid du Colombier * Maximum resolution in pixels pet inch (0 = no maximum). If
957dd7cddfSDavid du Colombier * the printer has a higher resolution than the maximum, trim
967dd7cddfSDavid du Colombier * the used resolution to the best one (dpi_chosen <= dpi_max,
977dd7cddfSDavid du Colombier * with dpi_chosen = dpi_printer / ratio).
987dd7cddfSDavid du Colombier */
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier /* Supported printer parameters are :
1017dd7cddfSDavid du Colombier *
1027dd7cddfSDavid du Colombier * -dBitsPerPixel=n
1037dd7cddfSDavid du Colombier * Override what the Window printer driver returns.
1047dd7cddfSDavid du Colombier *
1057dd7cddfSDavid du Colombier * -dNoCancel
1067dd7cddfSDavid du Colombier * Don't display cancel dialog box. Useful for unattended or
1077dd7cddfSDavid du Colombier * console EXE operation.
1087dd7cddfSDavid du Colombier *
1097dd7cddfSDavid du Colombier * -dQueryUser=n
1107dd7cddfSDavid du Colombier * Query user interactively for the destination printer, before
1117dd7cddfSDavid du Colombier * the device gets opened. This fills in the UserSettings dict
1127dd7cddfSDavid du Colombier * and the OutputFile name properties. The following values are
1137dd7cddfSDavid du Colombier * supported for n:
1147dd7cddfSDavid du Colombier * 1 => show standard Print dialog
1157dd7cddfSDavid du Colombier * 2 => show Print Setup dialog instead
1167dd7cddfSDavid du Colombier * 3 => select default printer
1177dd7cddfSDavid du Colombier * other, does nothing
1187dd7cddfSDavid du Colombier *
1197dd7cddfSDavid du Colombier * The /Duplex & /Tumble keys of the setpagedevice dict are supported
1207dd7cddfSDavid du Colombier * if the Windows printer supports duplex printing.
1217dd7cddfSDavid du Colombier */
1227dd7cddfSDavid du Colombier
1237dd7cddfSDavid du Colombier #include "gdevprn.h"
1247dd7cddfSDavid du Colombier #include "gdevpccm.h"
1257dd7cddfSDavid du Colombier
1267dd7cddfSDavid du Colombier #include "windows_.h"
1277dd7cddfSDavid du Colombier #include <shellapi.h>
1287dd7cddfSDavid du Colombier #include "gp_mswin.h"
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier #include "gp.h"
1313ff48bf5SDavid du Colombier #include "gpcheck.h"
1327dd7cddfSDavid du Colombier #include "commdlg.h"
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier
1357dd7cddfSDavid du Colombier /* Make sure we cast to the correct structure type. */
1367dd7cddfSDavid du Colombier typedef struct gx_device_win_pr2_s gx_device_win_pr2;
1377dd7cddfSDavid du Colombier
1387dd7cddfSDavid du Colombier #undef wdev
1397dd7cddfSDavid du Colombier #define wdev ((gx_device_win_pr2 *)dev)
1407dd7cddfSDavid du Colombier
1417dd7cddfSDavid du Colombier /* Device procedures */
1427dd7cddfSDavid du Colombier
1437dd7cddfSDavid du Colombier /* See gxdevice.h for the definitions of the procedures. */
1447dd7cddfSDavid du Colombier private dev_proc_open_device(win_pr2_open);
1457dd7cddfSDavid du Colombier private dev_proc_close_device(win_pr2_close);
1467dd7cddfSDavid du Colombier private dev_proc_print_page(win_pr2_print_page);
1477dd7cddfSDavid du Colombier private dev_proc_map_rgb_color(win_pr2_map_rgb_color);
1487dd7cddfSDavid du Colombier private dev_proc_map_color_rgb(win_pr2_map_color_rgb);
1497dd7cddfSDavid du Colombier private dev_proc_get_params(win_pr2_get_params);
1507dd7cddfSDavid du Colombier private dev_proc_put_params(win_pr2_put_params);
1517dd7cddfSDavid du Colombier
1527dd7cddfSDavid du Colombier private void win_pr2_set_bpp(gx_device * dev, int depth);
1537dd7cddfSDavid du Colombier
1547dd7cddfSDavid du Colombier private const gx_device_procs win_pr2_procs =
1557dd7cddfSDavid du Colombier prn_color_params_procs(win_pr2_open, gdev_prn_output_page, win_pr2_close,
1567dd7cddfSDavid du Colombier win_pr2_map_rgb_color, win_pr2_map_color_rgb,
1577dd7cddfSDavid du Colombier win_pr2_get_params, win_pr2_put_params);
1587dd7cddfSDavid du Colombier
1593ff48bf5SDavid du Colombier #define PARENT_WINDOW HWND_DESKTOP
1603ff48bf5SDavid du Colombier BOOL CALLBACK CancelDlgProc(HWND, UINT, WPARAM, LPARAM);
1613ff48bf5SDavid du Colombier BOOL CALLBACK AbortProc2(HDC, int);
1623ff48bf5SDavid du Colombier
1637dd7cddfSDavid du Colombier
1647dd7cddfSDavid du Colombier /* The device descriptor */
1657dd7cddfSDavid du Colombier typedef struct gx_device_win_pr2_s gx_device_win_pr2;
1667dd7cddfSDavid du Colombier struct gx_device_win_pr2_s {
1677dd7cddfSDavid du Colombier gx_device_common;
1687dd7cddfSDavid du Colombier gx_prn_device_common;
1697dd7cddfSDavid du Colombier HDC hdcprn;
1707dd7cddfSDavid du Colombier bool nocancel;
1717dd7cddfSDavid du Colombier
1727dd7cddfSDavid du Colombier int doc_page_begin; /* first page number in document */
1737dd7cddfSDavid du Colombier int doc_page_end; /* last page number in document */
1747dd7cddfSDavid du Colombier int user_page_begin; /* user's choice: first page to print */
1757dd7cddfSDavid du Colombier int user_page_end; /* user's choice: last page to print */
1767dd7cddfSDavid du Colombier int user_copies; /* user's choice: number of copies */
1777dd7cddfSDavid du Colombier int print_copies; /* number of times GS should print each page */
1787dd7cddfSDavid du Colombier float user_media_size[2]; /* width/height of media selected by user */
1797dd7cddfSDavid du Colombier char doc_name[200]; /* name of document for the spooler */
1807dd7cddfSDavid du Colombier char paper_name[64]; /* name of selected paper format */
1817dd7cddfSDavid du Colombier bool user_changed_settings; /* true if user validated dialog */
1827dd7cddfSDavid du Colombier int user_paper; /* user's choice: paper format */
1837dd7cddfSDavid du Colombier int user_orient; /* user's choice: paper orientation */
1847dd7cddfSDavid du Colombier int user_color; /* user's choice: color format */
1857dd7cddfSDavid du Colombier int max_dpi; /* maximum resolution in DPI */
1867dd7cddfSDavid du Colombier int ratio; /* stretch ratio when printing */
1877dd7cddfSDavid du Colombier int selected_bpp; /* selected bpp, memorised by win_pr2_set_bpp */
1883ff48bf5SDavid du Colombier bool tumble; /* tumble setting (with duplex) */
1893ff48bf5SDavid du Colombier int query_user; /* query user (-dQueryUser) */
1907dd7cddfSDavid du Colombier
1917dd7cddfSDavid du Colombier HANDLE win32_hdevmode; /* handle to device mode information */
1927dd7cddfSDavid du Colombier HANDLE win32_hdevnames; /* handle to device names information */
1937dd7cddfSDavid du Colombier
1947dd7cddfSDavid du Colombier DLGPROC lpfnAbortProc;
1957dd7cddfSDavid du Colombier DLGPROC lpfnCancelProc;
1963ff48bf5SDavid du Colombier HWND hDlgModeless;
1977dd7cddfSDavid du Colombier
1983ff48bf5SDavid du Colombier bool use_old_spool_name; /* user prefers old \\spool\ name */
1997dd7cddfSDavid du Colombier gx_device_win_pr2* original_device; /* used to detect copies */
2007dd7cddfSDavid du Colombier };
2017dd7cddfSDavid du Colombier
2027dd7cddfSDavid du Colombier gx_device_win_pr2 far_data gs_mswinpr2_device =
2037dd7cddfSDavid du Colombier {
2047dd7cddfSDavid du Colombier prn_device_std_body(gx_device_win_pr2, win_pr2_procs, "mswinpr2",
2057dd7cddfSDavid du Colombier DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 72.0, 72.0,
2067dd7cddfSDavid du Colombier 0, 0, 0, 0,
2077dd7cddfSDavid du Colombier 0, win_pr2_print_page), /* depth = 0 */
2087dd7cddfSDavid du Colombier 0, /* hdcprn */
2097dd7cddfSDavid du Colombier 0, /* nocancel */
2107dd7cddfSDavid du Colombier 0, /* doc_page_begin */
2117dd7cddfSDavid du Colombier 0, /* doc_page_end */
2127dd7cddfSDavid du Colombier 0, /* user_page_begin */
2137dd7cddfSDavid du Colombier 0, /* user_page_end */
2147dd7cddfSDavid du Colombier 1, /* user_copies */
2157dd7cddfSDavid du Colombier 1, /* print_copies */
2167dd7cddfSDavid du Colombier { 0.0, 0.0 }, /* user_media_size */
2177dd7cddfSDavid du Colombier { 0 }, /* doc_name */
2187dd7cddfSDavid du Colombier { 0 }, /* paper_name */
2197dd7cddfSDavid du Colombier 0, /* user_changed_settings */
2207dd7cddfSDavid du Colombier 0, /* user_paper */
2217dd7cddfSDavid du Colombier 0, /* user_orient */
2227dd7cddfSDavid du Colombier 0, /* user_color */
2237dd7cddfSDavid du Colombier 0, /* max_dpi */
2247dd7cddfSDavid du Colombier 0, /* ratio */
2257dd7cddfSDavid du Colombier 0, /* selected_bpp */
2263ff48bf5SDavid du Colombier false, /* tumble */
2273ff48bf5SDavid du Colombier -1, /* query_user */
2287dd7cddfSDavid du Colombier NULL, /* win32_hdevmode */
2297dd7cddfSDavid du Colombier NULL, /* win32_hdevnames */
2307dd7cddfSDavid du Colombier NULL, /* lpfnAbortProc */
2317dd7cddfSDavid du Colombier NULL, /* lpfnCancelProc */
232*593dc095SDavid du Colombier NULL, /* hDlgModeless */
2333ff48bf5SDavid du Colombier false, /* use_old_spool_name */
2347dd7cddfSDavid du Colombier NULL /* original_device */
2357dd7cddfSDavid du Colombier };
2367dd7cddfSDavid du Colombier
2377dd7cddfSDavid du Colombier /********************************************************************************/
2387dd7cddfSDavid du Colombier
2397dd7cddfSDavid du Colombier private int win_pr2_getdc(gx_device_win_pr2 * dev);
2407dd7cddfSDavid du Colombier private int win_pr2_update_dev(gx_device_win_pr2 * dev, LPDEVMODE pdevmode);
2417dd7cddfSDavid du Colombier private int win_pr2_update_win(gx_device_win_pr2 * dev, LPDEVMODE pdevmode);
2427dd7cddfSDavid du Colombier private int win_pr2_print_setup_interaction(gx_device_win_pr2 * dev, int mode);
2437dd7cddfSDavid du Colombier private int win_pr2_write_user_settings(gx_device_win_pr2 * dev, gs_param_list * plist);
2447dd7cddfSDavid du Colombier private int win_pr2_read_user_settings(gx_device_win_pr2 * dev, gs_param_list * plist);
2457dd7cddfSDavid du Colombier private void win_pr2_copy_check(gx_device_win_pr2 * dev);
2467dd7cddfSDavid du Colombier
2477dd7cddfSDavid du Colombier /********************************************************************************/
2487dd7cddfSDavid du Colombier
2497dd7cddfSDavid du Colombier /* Open the win_pr2 driver */
2507dd7cddfSDavid du Colombier private int
win_pr2_open(gx_device * dev)2517dd7cddfSDavid du Colombier win_pr2_open(gx_device * dev)
2527dd7cddfSDavid du Colombier {
2537dd7cddfSDavid du Colombier int code;
2547dd7cddfSDavid du Colombier int depth;
2557dd7cddfSDavid du Colombier PRINTDLG pd;
2567dd7cddfSDavid du Colombier POINT offset;
2577dd7cddfSDavid du Colombier POINT size;
2587dd7cddfSDavid du Colombier float m[4];
2597dd7cddfSDavid du Colombier FILE *pfile;
2607dd7cddfSDavid du Colombier DOCINFO docinfo;
2617dd7cddfSDavid du Colombier float ratio = 1.0;
2627dd7cddfSDavid du Colombier
2637dd7cddfSDavid du Colombier win_pr2_copy_check(wdev);
2647dd7cddfSDavid du Colombier
2657dd7cddfSDavid du Colombier /* get a HDC for the printer */
2667dd7cddfSDavid du Colombier if ((wdev->win32_hdevmode) &&
2677dd7cddfSDavid du Colombier (wdev->win32_hdevnames)) {
2687dd7cddfSDavid du Colombier /* The user has already had the opportunity to choose the output */
2697dd7cddfSDavid du Colombier /* file interactively. Just use the specified parameters. */
2707dd7cddfSDavid du Colombier
2717dd7cddfSDavid du Colombier LPDEVMODE devmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
2727dd7cddfSDavid du Colombier LPDEVNAMES devnames = (LPDEVNAMES) GlobalLock(wdev->win32_hdevnames);
2737dd7cddfSDavid du Colombier
2747dd7cddfSDavid du Colombier const char* driver = (char*)(devnames)+(devnames->wDriverOffset);
2757dd7cddfSDavid du Colombier const char* device = (char*)(devnames)+(devnames->wDeviceOffset);
2767dd7cddfSDavid du Colombier const char* output = (char*)(devnames)+(devnames->wOutputOffset);
2777dd7cddfSDavid du Colombier
2787dd7cddfSDavid du Colombier wdev->hdcprn = CreateDC(driver, device, output, devmode);
2797dd7cddfSDavid du Colombier
2807dd7cddfSDavid du Colombier GlobalUnlock(wdev->win32_hdevmode);
2817dd7cddfSDavid du Colombier GlobalUnlock(wdev->win32_hdevnames);
2827dd7cddfSDavid du Colombier
2837dd7cddfSDavid du Colombier if (wdev->hdcprn == NULL) {
2847dd7cddfSDavid du Colombier return gs_error_Fatal;
2857dd7cddfSDavid du Colombier }
2867dd7cddfSDavid du Colombier
2877dd7cddfSDavid du Colombier } else if (!win_pr2_getdc(wdev)) {
2887dd7cddfSDavid du Colombier /* couldn't get a printer from -sOutputFile= */
2897dd7cddfSDavid du Colombier /* Prompt with dialog box */
2907dd7cddfSDavid du Colombier
2917dd7cddfSDavid du Colombier LPDEVMODE devmode = NULL;
2927dd7cddfSDavid du Colombier memset(&pd, 0, sizeof(pd));
2937dd7cddfSDavid du Colombier
2947dd7cddfSDavid du Colombier pd.lStructSize = sizeof(pd);
2953ff48bf5SDavid du Colombier pd.hwndOwner = PARENT_WINDOW;
2967dd7cddfSDavid du Colombier pd.Flags = PD_RETURNDC;
2977dd7cddfSDavid du Colombier pd.nMinPage = wdev->doc_page_begin;
2987dd7cddfSDavid du Colombier pd.nMaxPage = wdev->doc_page_end;
2997dd7cddfSDavid du Colombier pd.nFromPage = wdev->user_page_begin;
3007dd7cddfSDavid du Colombier pd.nToPage = wdev->user_page_end;
3017dd7cddfSDavid du Colombier pd.nCopies = wdev->user_copies;
3027dd7cddfSDavid du Colombier
3037dd7cddfSDavid du Colombier if (!PrintDlg(&pd)) {
3047dd7cddfSDavid du Colombier /* device not opened - exit ghostscript */
3057dd7cddfSDavid du Colombier return gs_error_Fatal; /* exit Ghostscript cleanly */
3067dd7cddfSDavid du Colombier }
3077dd7cddfSDavid du Colombier
3087dd7cddfSDavid du Colombier devmode = GlobalLock(pd.hDevMode);
3097dd7cddfSDavid du Colombier win_pr2_update_dev(wdev,devmode);
3107dd7cddfSDavid du Colombier GlobalUnlock(pd.hDevMode);
3117dd7cddfSDavid du Colombier
3127dd7cddfSDavid du Colombier if (wdev->win32_hdevmode)
3137dd7cddfSDavid du Colombier GlobalFree(wdev->win32_hdevmode);
3147dd7cddfSDavid du Colombier if (wdev->win32_hdevnames)
3157dd7cddfSDavid du Colombier GlobalFree(wdev->win32_hdevnames);
3167dd7cddfSDavid du Colombier
3177dd7cddfSDavid du Colombier wdev->hdcprn = pd.hDC;
3187dd7cddfSDavid du Colombier wdev->win32_hdevmode = pd.hDevMode;
3197dd7cddfSDavid du Colombier wdev->win32_hdevnames = pd.hDevNames;
3207dd7cddfSDavid du Colombier
3217dd7cddfSDavid du Colombier pd.hDevMode = NULL;
3227dd7cddfSDavid du Colombier pd.hDevNames = NULL;
3237dd7cddfSDavid du Colombier }
3247dd7cddfSDavid du Colombier if (!(GetDeviceCaps(wdev->hdcprn, RASTERCAPS) != RC_DIBTODEV)) {
3253ff48bf5SDavid du Colombier errprintf( "Windows printer does not have RC_DIBTODEV\n");
3267dd7cddfSDavid du Colombier DeleteDC(wdev->hdcprn);
3277dd7cddfSDavid du Colombier return gs_error_limitcheck;
3287dd7cddfSDavid du Colombier }
3297dd7cddfSDavid du Colombier /* initialise printer, install abort proc */
3303ff48bf5SDavid du Colombier wdev->lpfnAbortProc = (DLGPROC) AbortProc2;
3317dd7cddfSDavid du Colombier SetAbortProc(wdev->hdcprn, (ABORTPROC) wdev->lpfnAbortProc);
3327dd7cddfSDavid du Colombier
3337dd7cddfSDavid du Colombier /*
3347dd7cddfSDavid du Colombier * Some versions of the Windows headers include lpszDatatype and fwType,
3357dd7cddfSDavid du Colombier * and some don't. Since we want to set these fields to zero anyway,
3367dd7cddfSDavid du Colombier * we just start by zeroing the whole structure.
3377dd7cddfSDavid du Colombier */
3387dd7cddfSDavid du Colombier memset(&docinfo, 0, sizeof(docinfo));
3397dd7cddfSDavid du Colombier docinfo.cbSize = sizeof(docinfo);
3407dd7cddfSDavid du Colombier docinfo.lpszDocName = wdev->doc_name;
3417dd7cddfSDavid du Colombier /*docinfo.lpszOutput = NULL;*/
3427dd7cddfSDavid du Colombier /*docinfo.lpszDatatype = NULL;*/
3437dd7cddfSDavid du Colombier /*docinfo.fwType = 0;*/
3447dd7cddfSDavid du Colombier
3457dd7cddfSDavid du Colombier if (docinfo.lpszDocName[0] == 0) {
3467dd7cddfSDavid du Colombier docinfo.lpszDocName = "Ghostscript output";
3477dd7cddfSDavid du Colombier }
3487dd7cddfSDavid du Colombier
3497dd7cddfSDavid du Colombier if (StartDoc(wdev->hdcprn, &docinfo) <= 0) {
3503ff48bf5SDavid du Colombier errprintf("Printer StartDoc failed (error %08x)\n", GetLastError());
3517dd7cddfSDavid du Colombier DeleteDC(wdev->hdcprn);
3527dd7cddfSDavid du Colombier return gs_error_limitcheck;
3537dd7cddfSDavid du Colombier }
3547dd7cddfSDavid du Colombier
3557dd7cddfSDavid du Colombier dev->x_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSX);
3567dd7cddfSDavid du Colombier dev->y_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSY);
3577dd7cddfSDavid du Colombier
3587dd7cddfSDavid du Colombier wdev->ratio = 1;
3597dd7cddfSDavid du Colombier
3607dd7cddfSDavid du Colombier if (wdev->max_dpi > 50) {
3617dd7cddfSDavid du Colombier
3627dd7cddfSDavid du Colombier float dpi_x = dev->x_pixels_per_inch;
3637dd7cddfSDavid du Colombier float dpi_y = dev->y_pixels_per_inch;
3647dd7cddfSDavid du Colombier
3657dd7cddfSDavid du Colombier while ((dev->x_pixels_per_inch > wdev->max_dpi)
3667dd7cddfSDavid du Colombier || (dev->y_pixels_per_inch > wdev->max_dpi)) {
3677dd7cddfSDavid du Colombier ratio += 1.0;
3687dd7cddfSDavid du Colombier wdev->ratio ++;
3697dd7cddfSDavid du Colombier dev->x_pixels_per_inch = dpi_x / ratio;
3707dd7cddfSDavid du Colombier dev->y_pixels_per_inch = dpi_y / ratio;
3717dd7cddfSDavid du Colombier }
3727dd7cddfSDavid du Colombier }
3737dd7cddfSDavid du Colombier
3747dd7cddfSDavid du Colombier size.x = GetDeviceCaps(wdev->hdcprn, PHYSICALWIDTH);
3757dd7cddfSDavid du Colombier size.y = GetDeviceCaps(wdev->hdcprn, PHYSICALHEIGHT);
3767dd7cddfSDavid du Colombier gx_device_set_width_height(dev, (int)(size.x / ratio), (int)(size.y / ratio));
3777dd7cddfSDavid du Colombier offset.x = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETX);
3787dd7cddfSDavid du Colombier offset.y = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETY);
3797dd7cddfSDavid du Colombier
3807dd7cddfSDavid du Colombier /* m[] gives margins in inches */
3817dd7cddfSDavid du Colombier m[0] /*left */ = offset.x / dev->x_pixels_per_inch / ratio;
3827dd7cddfSDavid du Colombier m[3] /*top */ = offset.y / dev->y_pixels_per_inch / ratio;
3837dd7cddfSDavid du Colombier m[2] /*right */ = (size.x - offset.x - GetDeviceCaps(wdev->hdcprn, HORZRES)) / dev->x_pixels_per_inch / ratio;
3847dd7cddfSDavid du Colombier m[1] /*bottom */ = (size.y - offset.y - GetDeviceCaps(wdev->hdcprn, VERTRES)) / dev->y_pixels_per_inch / ratio;
3857dd7cddfSDavid du Colombier gx_device_set_margins(dev, m, true);
3867dd7cddfSDavid du Colombier
3877dd7cddfSDavid du Colombier depth = dev->color_info.depth;
3887dd7cddfSDavid du Colombier if (depth == 0) {
3897dd7cddfSDavid du Colombier /* Set parameters that were unknown before opening device */
3907dd7cddfSDavid du Colombier /* Find out if the device supports color */
3917dd7cddfSDavid du Colombier /* We recognize 1, 4 (but use only 3), 8 and 24 bit color devices */
3927dd7cddfSDavid du Colombier depth = GetDeviceCaps(wdev->hdcprn, PLANES) * GetDeviceCaps(wdev->hdcprn, BITSPIXEL);
3937dd7cddfSDavid du Colombier }
3947dd7cddfSDavid du Colombier win_pr2_set_bpp(dev, depth);
3957dd7cddfSDavid du Colombier
3967dd7cddfSDavid du Colombier /* gdev_prn_open opens a temporary file which we don't want */
3977dd7cddfSDavid du Colombier /* so we specify the name now so we can delete it later */
3987dd7cddfSDavid du Colombier pfile = gp_open_scratch_file(gp_scratch_file_name_prefix,
3997dd7cddfSDavid du Colombier wdev->fname, "wb");
4007dd7cddfSDavid du Colombier fclose(pfile);
4017dd7cddfSDavid du Colombier code = gdev_prn_open(dev);
4027dd7cddfSDavid du Colombier /* delete unwanted temporary file */
4037dd7cddfSDavid du Colombier unlink(wdev->fname);
4047dd7cddfSDavid du Colombier
4057dd7cddfSDavid du Colombier if (!wdev->nocancel) {
4067dd7cddfSDavid du Colombier /* inform user of progress with dialog box and allow cancel */
4077dd7cddfSDavid du Colombier wdev->lpfnCancelProc = (DLGPROC) CancelDlgProc;
4083ff48bf5SDavid du Colombier wdev->hDlgModeless = CreateDialog(phInstance, "CancelDlgBox",
4093ff48bf5SDavid du Colombier PARENT_WINDOW, wdev->lpfnCancelProc);
4103ff48bf5SDavid du Colombier ShowWindow(wdev->hDlgModeless, SW_HIDE);
4117dd7cddfSDavid du Colombier }
4127dd7cddfSDavid du Colombier return code;
4137dd7cddfSDavid du Colombier };
4147dd7cddfSDavid du Colombier
4157dd7cddfSDavid du Colombier /* Close the win_pr2 driver */
4167dd7cddfSDavid du Colombier private int
win_pr2_close(gx_device * dev)4177dd7cddfSDavid du Colombier win_pr2_close(gx_device * dev)
4187dd7cddfSDavid du Colombier {
4197dd7cddfSDavid du Colombier int code;
4207dd7cddfSDavid du Colombier int aborted = FALSE;
4217dd7cddfSDavid du Colombier
4227dd7cddfSDavid du Colombier win_pr2_copy_check(wdev);
4237dd7cddfSDavid du Colombier
4247dd7cddfSDavid du Colombier /* Free resources */
4257dd7cddfSDavid du Colombier
4267dd7cddfSDavid du Colombier if (!wdev->nocancel) {
4273ff48bf5SDavid du Colombier if (!wdev->hDlgModeless)
4287dd7cddfSDavid du Colombier aborted = TRUE;
4297dd7cddfSDavid du Colombier else
4303ff48bf5SDavid du Colombier DestroyWindow(wdev->hDlgModeless);
4313ff48bf5SDavid du Colombier wdev->hDlgModeless = 0;
4327dd7cddfSDavid du Colombier }
4337dd7cddfSDavid du Colombier if (aborted)
4347dd7cddfSDavid du Colombier AbortDoc(wdev->hdcprn);
4357dd7cddfSDavid du Colombier else
4367dd7cddfSDavid du Colombier EndDoc(wdev->hdcprn);
4377dd7cddfSDavid du Colombier
4387dd7cddfSDavid du Colombier DeleteDC(wdev->hdcprn);
4397dd7cddfSDavid du Colombier
4407dd7cddfSDavid du Colombier if (wdev->win32_hdevmode != NULL) {
4417dd7cddfSDavid du Colombier GlobalFree(wdev->win32_hdevmode);
4427dd7cddfSDavid du Colombier wdev->win32_hdevmode = NULL;
4437dd7cddfSDavid du Colombier }
4447dd7cddfSDavid du Colombier if (wdev->win32_hdevnames != NULL) {
4457dd7cddfSDavid du Colombier GlobalFree(wdev->win32_hdevnames);
4467dd7cddfSDavid du Colombier wdev->win32_hdevnames = NULL;
4477dd7cddfSDavid du Colombier }
4487dd7cddfSDavid du Colombier
4497dd7cddfSDavid du Colombier code = gdev_prn_close(dev);
4507dd7cddfSDavid du Colombier return code;
4517dd7cddfSDavid du Colombier }
4527dd7cddfSDavid du Colombier
4537dd7cddfSDavid du Colombier
4547dd7cddfSDavid du Colombier /* ------ Internal routines ------ */
4557dd7cddfSDavid du Colombier
4567dd7cddfSDavid du Colombier #undef wdev
4577dd7cddfSDavid du Colombier #define wdev ((gx_device_win_pr2 *)pdev)
4587dd7cddfSDavid du Colombier
4597dd7cddfSDavid du Colombier /********************************************************************************/
4607dd7cddfSDavid du Colombier
4617dd7cddfSDavid du Colombier /* ------ Private definitions ------ */
4627dd7cddfSDavid du Colombier
4637dd7cddfSDavid du Colombier
4647dd7cddfSDavid du Colombier /* new win_pr2_print_page routine */
4657dd7cddfSDavid du Colombier
4667dd7cddfSDavid du Colombier /* Write BMP header to memory, then send bitmap to printer */
4677dd7cddfSDavid du Colombier /* one scan line at a time */
4687dd7cddfSDavid du Colombier private int
win_pr2_print_page(gx_device_printer * pdev,FILE * file)4697dd7cddfSDavid du Colombier win_pr2_print_page(gx_device_printer * pdev, FILE * file)
4707dd7cddfSDavid du Colombier {
4717dd7cddfSDavid du Colombier int raster = gdev_prn_raster(pdev);
4727dd7cddfSDavid du Colombier
4737dd7cddfSDavid du Colombier /* BMP scan lines are padded to 32 bits. */
4747dd7cddfSDavid du Colombier ulong bmp_raster = raster + (-raster & 3);
4757dd7cddfSDavid du Colombier ulong bmp_raster_multi;
4767dd7cddfSDavid du Colombier int scan_lines, yslice, lines, i;
4777dd7cddfSDavid du Colombier int width;
4787dd7cddfSDavid du Colombier int depth = pdev->color_info.depth;
4797dd7cddfSDavid du Colombier byte *row;
4807dd7cddfSDavid du Colombier int y;
4817dd7cddfSDavid du Colombier int code = 0; /* return code */
4827dd7cddfSDavid du Colombier MSG msg;
4837dd7cddfSDavid du Colombier char dlgtext[32];
4847dd7cddfSDavid du Colombier HGLOBAL hrow;
4857dd7cddfSDavid du Colombier int ratio = ((gx_device_win_pr2 *)pdev)->ratio;
4867dd7cddfSDavid du Colombier
4877dd7cddfSDavid du Colombier struct bmi_s {
4887dd7cddfSDavid du Colombier BITMAPINFOHEADER h;
4897dd7cddfSDavid du Colombier RGBQUAD pal[256];
4907dd7cddfSDavid du Colombier } bmi;
4917dd7cddfSDavid du Colombier
4927dd7cddfSDavid du Colombier scan_lines = dev_print_scan_lines(pdev);
4937dd7cddfSDavid du Colombier width = (int)(pdev->width - ((dev_l_margin(pdev) + dev_r_margin(pdev) -
4947dd7cddfSDavid du Colombier dev_x_offset(pdev)) * pdev->x_pixels_per_inch));
4957dd7cddfSDavid du Colombier
4967dd7cddfSDavid du Colombier yslice = 65535 / bmp_raster; /* max lines in 64k */
4977dd7cddfSDavid du Colombier bmp_raster_multi = bmp_raster * yslice;
4987dd7cddfSDavid du Colombier hrow = GlobalAlloc(0, bmp_raster_multi);
4997dd7cddfSDavid du Colombier row = GlobalLock(hrow);
5007dd7cddfSDavid du Colombier if (row == 0) /* can't allocate row buffer */
5017dd7cddfSDavid du Colombier return_error(gs_error_VMerror);
5027dd7cddfSDavid du Colombier
5037dd7cddfSDavid du Colombier /* Write the info header. */
5047dd7cddfSDavid du Colombier
5057dd7cddfSDavid du Colombier bmi.h.biSize = sizeof(bmi.h);
5067dd7cddfSDavid du Colombier bmi.h.biWidth = pdev->width; /* wdev->mdev.width; */
5077dd7cddfSDavid du Colombier bmi.h.biHeight = yslice;
5087dd7cddfSDavid du Colombier bmi.h.biPlanes = 1;
5097dd7cddfSDavid du Colombier bmi.h.biBitCount = pdev->color_info.depth;
5107dd7cddfSDavid du Colombier bmi.h.biCompression = 0;
5117dd7cddfSDavid du Colombier bmi.h.biSizeImage = 0; /* default */
5127dd7cddfSDavid du Colombier bmi.h.biXPelsPerMeter = 0; /* default */
5137dd7cddfSDavid du Colombier bmi.h.biYPelsPerMeter = 0; /* default */
5147dd7cddfSDavid du Colombier
5157dd7cddfSDavid du Colombier StartPage(wdev->hdcprn);
5167dd7cddfSDavid du Colombier
5177dd7cddfSDavid du Colombier /* Write the palette. */
5187dd7cddfSDavid du Colombier
5197dd7cddfSDavid du Colombier if (depth <= 8) {
5207dd7cddfSDavid du Colombier int i;
5217dd7cddfSDavid du Colombier gx_color_value rgb[3];
5227dd7cddfSDavid du Colombier LPRGBQUAD pq;
5237dd7cddfSDavid du Colombier
5247dd7cddfSDavid du Colombier bmi.h.biClrUsed = 1 << depth;
5257dd7cddfSDavid du Colombier bmi.h.biClrImportant = 1 << depth;
5267dd7cddfSDavid du Colombier for (i = 0; i != 1 << depth; i++) {
5277dd7cddfSDavid du Colombier (*dev_proc(pdev, map_color_rgb)) ((gx_device *) pdev,
5287dd7cddfSDavid du Colombier (gx_color_index) i, rgb);
5297dd7cddfSDavid du Colombier pq = &bmi.pal[i];
5307dd7cddfSDavid du Colombier pq->rgbRed = gx_color_value_to_byte(rgb[0]);
5317dd7cddfSDavid du Colombier pq->rgbGreen = gx_color_value_to_byte(rgb[1]);
5327dd7cddfSDavid du Colombier pq->rgbBlue = gx_color_value_to_byte(rgb[2]);
5337dd7cddfSDavid du Colombier pq->rgbReserved = 0;
5347dd7cddfSDavid du Colombier }
5357dd7cddfSDavid du Colombier } else {
5367dd7cddfSDavid du Colombier bmi.h.biClrUsed = 0;
5377dd7cddfSDavid du Colombier bmi.h.biClrImportant = 0;
5387dd7cddfSDavid du Colombier }
5397dd7cddfSDavid du Colombier
5407dd7cddfSDavid du Colombier if (!wdev->nocancel) {
5417dd7cddfSDavid du Colombier sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount) + 1);
5423ff48bf5SDavid du Colombier SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PRINTING), dlgtext);
5433ff48bf5SDavid du Colombier ShowWindow(wdev->hDlgModeless, SW_SHOW);
5447dd7cddfSDavid du Colombier }
5457dd7cddfSDavid du Colombier for (y = 0; y < scan_lines;) {
5467dd7cddfSDavid du Colombier /* copy slice to row buffer */
5477dd7cddfSDavid du Colombier if (y > scan_lines - yslice)
5487dd7cddfSDavid du Colombier lines = scan_lines - y;
5497dd7cddfSDavid du Colombier else
5507dd7cddfSDavid du Colombier lines = yslice;
5517dd7cddfSDavid du Colombier for (i = 0; i < lines; i++)
5527dd7cddfSDavid du Colombier gdev_prn_copy_scan_lines(pdev, y + i,
5537dd7cddfSDavid du Colombier row + (bmp_raster * (lines - 1 - i)), raster);
5547dd7cddfSDavid du Colombier
5557dd7cddfSDavid du Colombier if (ratio > 1) {
5567dd7cddfSDavid du Colombier StretchDIBits(wdev->hdcprn, 0, y*ratio, pdev->width*ratio, lines*ratio,
5577dd7cddfSDavid du Colombier 0, 0, pdev->width, lines,
5587dd7cddfSDavid du Colombier row,
5597dd7cddfSDavid du Colombier (BITMAPINFO FAR *) & bmi, DIB_RGB_COLORS, SRCCOPY);
5607dd7cddfSDavid du Colombier } else {
5617dd7cddfSDavid du Colombier SetDIBitsToDevice(wdev->hdcprn, 0, y, pdev->width, lines,
5627dd7cddfSDavid du Colombier 0, 0, 0, lines,
5637dd7cddfSDavid du Colombier row,
5647dd7cddfSDavid du Colombier (BITMAPINFO FAR *) & bmi, DIB_RGB_COLORS);
5657dd7cddfSDavid du Colombier }
5667dd7cddfSDavid du Colombier y += lines;
5677dd7cddfSDavid du Colombier
5687dd7cddfSDavid du Colombier if (!wdev->nocancel) {
5697dd7cddfSDavid du Colombier /* inform user of progress */
5707dd7cddfSDavid du Colombier sprintf(dlgtext, "%d%% done", (int)(y * 100L / scan_lines));
5713ff48bf5SDavid du Colombier SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE), dlgtext);
5727dd7cddfSDavid du Colombier }
5737dd7cddfSDavid du Colombier /* process message loop */
5743ff48bf5SDavid du Colombier while (PeekMessage(&msg, wdev->hDlgModeless, 0, 0, PM_REMOVE)) {
5753ff48bf5SDavid du Colombier if ((wdev->hDlgModeless == 0) || !IsDialogMessage(wdev->hDlgModeless, &msg)) {
5767dd7cddfSDavid du Colombier TranslateMessage(&msg);
5777dd7cddfSDavid du Colombier DispatchMessage(&msg);
5787dd7cddfSDavid du Colombier }
5797dd7cddfSDavid du Colombier }
5803ff48bf5SDavid du Colombier if ((!wdev->nocancel) && (wdev->hDlgModeless == 0)) {
5817dd7cddfSDavid du Colombier /* user pressed cancel button */
5827dd7cddfSDavid du Colombier break;
5837dd7cddfSDavid du Colombier }
5847dd7cddfSDavid du Colombier }
5857dd7cddfSDavid du Colombier
5863ff48bf5SDavid du Colombier if ((!wdev->nocancel) && (wdev->hDlgModeless == 0))
5877dd7cddfSDavid du Colombier code = gs_error_Fatal; /* exit Ghostscript cleanly */
5887dd7cddfSDavid du Colombier else {
5897dd7cddfSDavid du Colombier /* push out the page */
5907dd7cddfSDavid du Colombier if (!wdev->nocancel)
5913ff48bf5SDavid du Colombier SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE),
5927dd7cddfSDavid du Colombier "Ejecting page...");
5937dd7cddfSDavid du Colombier EndPage(wdev->hdcprn);
5947dd7cddfSDavid du Colombier if (!wdev->nocancel)
5953ff48bf5SDavid du Colombier ShowWindow(wdev->hDlgModeless, SW_HIDE);
5967dd7cddfSDavid du Colombier }
5977dd7cddfSDavid du Colombier
5987dd7cddfSDavid du Colombier GlobalUnlock(hrow);
5997dd7cddfSDavid du Colombier GlobalFree(hrow);
6007dd7cddfSDavid du Colombier
6017dd7cddfSDavid du Colombier return code;
6027dd7cddfSDavid du Colombier }
6037dd7cddfSDavid du Colombier
6047dd7cddfSDavid du Colombier /* combined color mappers */
6057dd7cddfSDavid du Colombier
6067dd7cddfSDavid du Colombier /* 24-bit color mappers (taken from gdevmem2.c). */
6077dd7cddfSDavid du Colombier /* Note that Windows expects RGB values in the order B,G,R. */
6087dd7cddfSDavid du Colombier
6097dd7cddfSDavid du Colombier /* Map a r-g-b color to a color index. */
6107dd7cddfSDavid du Colombier private gx_color_index
win_pr2_map_rgb_color(gx_device * dev,const gx_color_value cv[])611*593dc095SDavid du Colombier win_pr2_map_rgb_color(gx_device * dev, const gx_color_value cv[])
6127dd7cddfSDavid du Colombier {
613*593dc095SDavid du Colombier gx_color_value r = cv[0];
614*593dc095SDavid du Colombier gx_color_value g = cv[1];
615*593dc095SDavid du Colombier gx_color_value b = cv[2];
6167dd7cddfSDavid du Colombier switch (dev->color_info.depth) {
6177dd7cddfSDavid du Colombier case 1:
618*593dc095SDavid du Colombier return gdev_prn_map_rgb_color(dev, cv);
6197dd7cddfSDavid du Colombier case 4:
6207dd7cddfSDavid du Colombier /* use only 8 colors */
6217dd7cddfSDavid du Colombier return (r > (gx_max_color_value / 2 + 1) ? 4 : 0) +
6227dd7cddfSDavid du Colombier (g > (gx_max_color_value / 2 + 1) ? 2 : 0) +
6237dd7cddfSDavid du Colombier (b > (gx_max_color_value / 2 + 1) ? 1 : 0);
6247dd7cddfSDavid du Colombier case 8:
625*593dc095SDavid du Colombier return pc_8bit_map_rgb_color(dev, cv);
6267dd7cddfSDavid du Colombier case 24:
6277dd7cddfSDavid du Colombier return gx_color_value_to_byte(r) +
6287dd7cddfSDavid du Colombier ((uint) gx_color_value_to_byte(g) << 8) +
6297dd7cddfSDavid du Colombier ((ulong) gx_color_value_to_byte(b) << 16);
6307dd7cddfSDavid du Colombier }
6317dd7cddfSDavid du Colombier return 0; /* error */
6327dd7cddfSDavid du Colombier }
6337dd7cddfSDavid du Colombier
6347dd7cddfSDavid du Colombier /* Map a color index to a r-g-b color. */
6357dd7cddfSDavid du Colombier private int
win_pr2_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])6367dd7cddfSDavid du Colombier win_pr2_map_color_rgb(gx_device * dev, gx_color_index color,
6377dd7cddfSDavid du Colombier gx_color_value prgb[3])
6387dd7cddfSDavid du Colombier {
6397dd7cddfSDavid du Colombier switch (dev->color_info.depth) {
6407dd7cddfSDavid du Colombier case 1:
6417dd7cddfSDavid du Colombier gdev_prn_map_color_rgb(dev, color, prgb);
6427dd7cddfSDavid du Colombier break;
6437dd7cddfSDavid du Colombier case 4:
6447dd7cddfSDavid du Colombier /* use only 8 colors */
6457dd7cddfSDavid du Colombier prgb[0] = (color & 4) ? gx_max_color_value : 0;
6467dd7cddfSDavid du Colombier prgb[1] = (color & 2) ? gx_max_color_value : 0;
6477dd7cddfSDavid du Colombier prgb[2] = (color & 1) ? gx_max_color_value : 0;
6487dd7cddfSDavid du Colombier break;
6497dd7cddfSDavid du Colombier case 8:
6507dd7cddfSDavid du Colombier pc_8bit_map_color_rgb(dev, color, prgb);
6517dd7cddfSDavid du Colombier break;
6527dd7cddfSDavid du Colombier case 24:
6537dd7cddfSDavid du Colombier prgb[2] = gx_color_value_from_byte(color >> 16);
6547dd7cddfSDavid du Colombier prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
6557dd7cddfSDavid du Colombier prgb[0] = gx_color_value_from_byte(color & 0xff);
6567dd7cddfSDavid du Colombier break;
6577dd7cddfSDavid du Colombier }
6587dd7cddfSDavid du Colombier return 0;
6597dd7cddfSDavid du Colombier }
6607dd7cddfSDavid du Colombier
6617dd7cddfSDavid du Colombier void
win_pr2_set_bpp(gx_device * dev,int depth)6627dd7cddfSDavid du Colombier win_pr2_set_bpp(gx_device * dev, int depth)
6637dd7cddfSDavid du Colombier {
6647dd7cddfSDavid du Colombier if (depth > 8) {
6657dd7cddfSDavid du Colombier static const gx_device_color_info win_pr2_24color = dci_std_color(24);
6667dd7cddfSDavid du Colombier
6677dd7cddfSDavid du Colombier dev->color_info = win_pr2_24color;
6683ff48bf5SDavid du Colombier depth = 24;
6697dd7cddfSDavid du Colombier } else if (depth >= 8) {
6707dd7cddfSDavid du Colombier /* 8-bit (SuperVGA-style) color. */
6717dd7cddfSDavid du Colombier /* (Uses a fixed palette of 3,3,2 bits.) */
6727dd7cddfSDavid du Colombier static const gx_device_color_info win_pr2_8color = dci_pc_8bit;
6737dd7cddfSDavid du Colombier
6747dd7cddfSDavid du Colombier dev->color_info = win_pr2_8color;
6753ff48bf5SDavid du Colombier depth = 8;
6767dd7cddfSDavid du Colombier } else if (depth >= 3) {
6777dd7cddfSDavid du Colombier /* 3 plane printer */
6787dd7cddfSDavid du Colombier /* suitable for impact dot matrix CMYK printers */
6797dd7cddfSDavid du Colombier /* create 4-bit bitmap, but only use 8 colors */
6803ff48bf5SDavid du Colombier static const gx_device_color_info win_pr2_4color = dci_values(3, 4, 1, 1, 2, 2);
6817dd7cddfSDavid du Colombier
6827dd7cddfSDavid du Colombier dev->color_info = win_pr2_4color;
6833ff48bf5SDavid du Colombier depth = 4;
6847dd7cddfSDavid du Colombier } else { /* default is black_and_white */
6857dd7cddfSDavid du Colombier static const gx_device_color_info win_pr2_1color = dci_std_color(1);
6867dd7cddfSDavid du Colombier
6877dd7cddfSDavid du Colombier dev->color_info = win_pr2_1color;
6883ff48bf5SDavid du Colombier depth = 1;
6897dd7cddfSDavid du Colombier }
6907dd7cddfSDavid du Colombier
6917dd7cddfSDavid du Colombier ((gx_device_win_pr2 *)dev)->selected_bpp = depth;
692*593dc095SDavid du Colombier
693*593dc095SDavid du Colombier /* copy encode/decode procedures */
694*593dc095SDavid du Colombier dev->procs.encode_color = dev->procs.map_rgb_color;
695*593dc095SDavid du Colombier dev->procs.decode_color = dev->procs.map_color_rgb;
696*593dc095SDavid du Colombier if (depth == 1) {
697*593dc095SDavid du Colombier dev->procs.get_color_mapping_procs =
698*593dc095SDavid du Colombier gx_default_DevGray_get_color_mapping_procs;
699*593dc095SDavid du Colombier dev->procs.get_color_comp_index =
700*593dc095SDavid du Colombier gx_default_DevGray_get_color_comp_index;
701*593dc095SDavid du Colombier }
702*593dc095SDavid du Colombier else {
703*593dc095SDavid du Colombier dev->procs.get_color_mapping_procs =
704*593dc095SDavid du Colombier gx_default_DevRGB_get_color_mapping_procs;
705*593dc095SDavid du Colombier dev->procs.get_color_comp_index =
706*593dc095SDavid du Colombier gx_default_DevRGB_get_color_comp_index;
707*593dc095SDavid du Colombier }
7087dd7cddfSDavid du Colombier }
7097dd7cddfSDavid du Colombier
7107dd7cddfSDavid du Colombier /********************************************************************************/
7117dd7cddfSDavid du Colombier
7127dd7cddfSDavid du Colombier /* Get device parameters */
7137dd7cddfSDavid du Colombier int
win_pr2_get_params(gx_device * pdev,gs_param_list * plist)7147dd7cddfSDavid du Colombier win_pr2_get_params(gx_device * pdev, gs_param_list * plist)
7157dd7cddfSDavid du Colombier {
7167dd7cddfSDavid du Colombier int code = gdev_prn_get_params(pdev, plist);
7177dd7cddfSDavid du Colombier
7187dd7cddfSDavid du Colombier win_pr2_copy_check(wdev);
7197dd7cddfSDavid du Colombier
7207dd7cddfSDavid du Colombier if (code >= 0)
7217dd7cddfSDavid du Colombier code = param_write_bool(plist, "NoCancel",
7227dd7cddfSDavid du Colombier &(wdev->nocancel));
7237dd7cddfSDavid du Colombier if (code >= 0)
724*593dc095SDavid du Colombier code = param_write_int(plist, "QueryUser",
7253ff48bf5SDavid du Colombier &(wdev->query_user));
7263ff48bf5SDavid du Colombier if (code >= 0)
7277dd7cddfSDavid du Colombier code = win_pr2_write_user_settings(wdev, plist);
7287dd7cddfSDavid du Colombier
7293ff48bf5SDavid du Colombier if ((code >= 0) && (wdev->Duplex_set > 0))
7303ff48bf5SDavid du Colombier code = param_write_bool(plist, "Tumble",
7313ff48bf5SDavid du Colombier &(wdev->tumble));
7323ff48bf5SDavid du Colombier
7337dd7cddfSDavid du Colombier return code;
7347dd7cddfSDavid du Colombier }
7357dd7cddfSDavid du Colombier
7367dd7cddfSDavid du Colombier
7377dd7cddfSDavid du Colombier /* We implement this ourselves so that we can change BitsPerPixel */
7387dd7cddfSDavid du Colombier /* before the device is opened */
7397dd7cddfSDavid du Colombier int
win_pr2_put_params(gx_device * pdev,gs_param_list * plist)7407dd7cddfSDavid du Colombier win_pr2_put_params(gx_device * pdev, gs_param_list * plist)
7417dd7cddfSDavid du Colombier {
7427dd7cddfSDavid du Colombier int ecode = 0, code;
7437dd7cddfSDavid du Colombier int old_bpp = pdev->color_info.depth;
7447dd7cddfSDavid du Colombier int bpp = old_bpp;
7453ff48bf5SDavid du Colombier bool tumble = wdev->tumble;
7467dd7cddfSDavid du Colombier bool nocancel = wdev->nocancel;
7477dd7cddfSDavid du Colombier int queryuser = 0;
7487dd7cddfSDavid du Colombier bool old_duplex = wdev->Duplex;
7493ff48bf5SDavid du Colombier bool old_tumble = wdev->tumble;
7507dd7cddfSDavid du Colombier int old_orient = wdev->user_orient;
7517dd7cddfSDavid du Colombier int old_color = wdev->user_color;
7527dd7cddfSDavid du Colombier int old_paper = wdev->user_paper;
7537dd7cddfSDavid du Colombier int old_mx_dpi = wdev->max_dpi;
7547dd7cddfSDavid du Colombier
7557dd7cddfSDavid du Colombier if (wdev->Duplex_set < 0) {
7567dd7cddfSDavid du Colombier wdev->Duplex_set = 0;
7577dd7cddfSDavid du Colombier wdev->Duplex = false;
7583ff48bf5SDavid du Colombier wdev->tumble = false;
7597dd7cddfSDavid du Colombier }
7607dd7cddfSDavid du Colombier
7617dd7cddfSDavid du Colombier win_pr2_copy_check(wdev);
7627dd7cddfSDavid du Colombier
7637dd7cddfSDavid du Colombier code = win_pr2_read_user_settings(wdev, plist);
7647dd7cddfSDavid du Colombier
7657dd7cddfSDavid du Colombier switch (code = param_read_int(plist, "BitsPerPixel", &bpp)) {
7667dd7cddfSDavid du Colombier case 0:
7677dd7cddfSDavid du Colombier if (pdev->is_open) {
7687dd7cddfSDavid du Colombier if (wdev->selected_bpp == bpp) {
7697dd7cddfSDavid du Colombier break;
7707dd7cddfSDavid du Colombier }
7717dd7cddfSDavid du Colombier ecode = gs_error_rangecheck;
7727dd7cddfSDavid du Colombier } else { /* change dev->color_info is valid before device is opened */
7737dd7cddfSDavid du Colombier win_pr2_set_bpp(pdev, bpp);
7747dd7cddfSDavid du Colombier break;
7757dd7cddfSDavid du Colombier }
7767dd7cddfSDavid du Colombier goto bppe;
7777dd7cddfSDavid du Colombier default:
7787dd7cddfSDavid du Colombier ecode = code;
7797dd7cddfSDavid du Colombier bppe:param_signal_error(plist, "BitsPerPixel", ecode);
7807dd7cddfSDavid du Colombier case 1:
7817dd7cddfSDavid du Colombier break;
7827dd7cddfSDavid du Colombier }
7837dd7cddfSDavid du Colombier
7847dd7cddfSDavid du Colombier switch (code = param_read_bool(plist, "NoCancel", &nocancel)) {
7857dd7cddfSDavid du Colombier case 0:
7867dd7cddfSDavid du Colombier if (pdev->is_open) {
7877dd7cddfSDavid du Colombier if (wdev->nocancel == nocancel) {
7887dd7cddfSDavid du Colombier break;
7897dd7cddfSDavid du Colombier }
7907dd7cddfSDavid du Colombier ecode = gs_error_rangecheck;
7917dd7cddfSDavid du Colombier } else {
7927dd7cddfSDavid du Colombier wdev->nocancel = nocancel;
7937dd7cddfSDavid du Colombier break;
7947dd7cddfSDavid du Colombier }
7957dd7cddfSDavid du Colombier goto nocancele;
7967dd7cddfSDavid du Colombier default:
7977dd7cddfSDavid du Colombier ecode = code;
7987dd7cddfSDavid du Colombier nocancele:param_signal_error(plist, "NoCancel", ecode);
7997dd7cddfSDavid du Colombier case 1:
8007dd7cddfSDavid du Colombier break;
8017dd7cddfSDavid du Colombier }
8027dd7cddfSDavid du Colombier
8033ff48bf5SDavid du Colombier switch (code = param_read_bool(plist, "Tumble", &tumble)) {
8043ff48bf5SDavid du Colombier case 0:
8053ff48bf5SDavid du Colombier wdev->tumble = tumble;
8063ff48bf5SDavid du Colombier break;
8073ff48bf5SDavid du Colombier default:
8083ff48bf5SDavid du Colombier ecode = code;
8093ff48bf5SDavid du Colombier param_signal_error(plist, "Tumble", ecode);
8103ff48bf5SDavid du Colombier case 1:
8113ff48bf5SDavid du Colombier break;
8123ff48bf5SDavid du Colombier }
8133ff48bf5SDavid du Colombier
8147dd7cddfSDavid du Colombier switch (code = param_read_int(plist, "QueryUser", &queryuser)) {
8157dd7cddfSDavid du Colombier case 0:
8167dd7cddfSDavid du Colombier if ((queryuser > 0) &&
8177dd7cddfSDavid du Colombier (queryuser < 4)) {
8187dd7cddfSDavid du Colombier win_pr2_print_setup_interaction(wdev, queryuser);
8197dd7cddfSDavid du Colombier }
8207dd7cddfSDavid du Colombier break;
8217dd7cddfSDavid du Colombier default:
8227dd7cddfSDavid du Colombier ecode = code;
8237dd7cddfSDavid du Colombier param_signal_error(plist, "QueryUser", ecode);
8247dd7cddfSDavid du Colombier case 1:
8257dd7cddfSDavid du Colombier break;
8267dd7cddfSDavid du Colombier }
8277dd7cddfSDavid du Colombier
8287dd7cddfSDavid du Colombier if (ecode >= 0)
8297dd7cddfSDavid du Colombier ecode = gdev_prn_put_params(pdev, plist);
8307dd7cddfSDavid du Colombier
8317dd7cddfSDavid du Colombier if (wdev->win32_hdevmode && wdev->hdcprn) {
8327dd7cddfSDavid du Colombier if ( (old_duplex != wdev->Duplex)
8333ff48bf5SDavid du Colombier || (old_tumble != wdev->tumble)
8347dd7cddfSDavid du Colombier || (old_orient != wdev->user_orient)
8357dd7cddfSDavid du Colombier || (old_color != wdev->user_color)
8367dd7cddfSDavid du Colombier || (old_paper != wdev->user_paper)
8377dd7cddfSDavid du Colombier || (old_mx_dpi != wdev->max_dpi) ) {
8387dd7cddfSDavid du Colombier
8397dd7cddfSDavid du Colombier LPDEVMODE pdevmode = GlobalLock(wdev->win32_hdevmode);
8407dd7cddfSDavid du Colombier
8417dd7cddfSDavid du Colombier if (pdevmode) {
8427dd7cddfSDavid du Colombier win_pr2_update_win(wdev, pdevmode);
8437dd7cddfSDavid du Colombier ResetDC(wdev->hdcprn, pdevmode);
8447dd7cddfSDavid du Colombier GlobalUnlock(pdevmode);
8457dd7cddfSDavid du Colombier }
8467dd7cddfSDavid du Colombier }
8477dd7cddfSDavid du Colombier }
8487dd7cddfSDavid du Colombier
8497dd7cddfSDavid du Colombier return ecode;
8507dd7cddfSDavid du Colombier }
8517dd7cddfSDavid du Colombier
8527dd7cddfSDavid du Colombier #undef wdev
8537dd7cddfSDavid du Colombier
8547dd7cddfSDavid du Colombier /********************************************************************************/
8557dd7cddfSDavid du Colombier
8567dd7cddfSDavid du Colombier
8577dd7cddfSDavid du Colombier /* Get Device Context for printer */
8587dd7cddfSDavid du Colombier private int
win_pr2_getdc(gx_device_win_pr2 * wdev)8597dd7cddfSDavid du Colombier win_pr2_getdc(gx_device_win_pr2 * wdev)
8607dd7cddfSDavid du Colombier {
8617dd7cddfSDavid du Colombier char *device;
8627dd7cddfSDavid du Colombier char *devices;
8637dd7cddfSDavid du Colombier char *p;
8647dd7cddfSDavid du Colombier char driverbuf[512];
8657dd7cddfSDavid du Colombier char *driver;
8667dd7cddfSDavid du Colombier char *output;
8677dd7cddfSDavid du Colombier char *devcap;
8687dd7cddfSDavid du Colombier int devcapsize;
8697dd7cddfSDavid du Colombier int size;
8707dd7cddfSDavid du Colombier
8717dd7cddfSDavid du Colombier int i, n;
8727dd7cddfSDavid du Colombier POINT *pp;
8737dd7cddfSDavid du Colombier int paperindex;
8747dd7cddfSDavid du Colombier int paperwidth, paperheight;
8757dd7cddfSDavid du Colombier int orientation;
8767dd7cddfSDavid du Colombier int papersize;
8777dd7cddfSDavid du Colombier char papername[64];
8787dd7cddfSDavid du Colombier char drvname[32];
8797dd7cddfSDavid du Colombier HINSTANCE hlib;
8807dd7cddfSDavid du Colombier LPFNDEVMODE pfnExtDeviceMode;
8817dd7cddfSDavid du Colombier LPFNDEVCAPS pfnDeviceCapabilities;
8827dd7cddfSDavid du Colombier LPDEVMODE podevmode, pidevmode;
8837dd7cddfSDavid du Colombier
8847dd7cddfSDavid du Colombier HANDLE hprinter;
8857dd7cddfSDavid du Colombier
8867dd7cddfSDavid du Colombier /* first try to derive the printer name from -sOutputFile= */
8873ff48bf5SDavid du Colombier /* is printer if name prefixed by \\spool\ or by %printer% */
8883ff48bf5SDavid du Colombier if (is_spool(wdev->fname)) {
8897dd7cddfSDavid du Colombier device = wdev->fname + 8; /* skip over \\spool\ */
8903ff48bf5SDavid du Colombier wdev->use_old_spool_name = true;
8913ff48bf5SDavid du Colombier } else if (strncmp("%printer%",wdev->fname,9) == 0) {
8923ff48bf5SDavid du Colombier device = wdev->fname + 9; /* skip over %printer% */
8933ff48bf5SDavid du Colombier wdev->use_old_spool_name = false;
8943ff48bf5SDavid du Colombier } else {
8957dd7cddfSDavid du Colombier return FALSE;
8963ff48bf5SDavid du Colombier }
8977dd7cddfSDavid du Colombier
8987dd7cddfSDavid du Colombier /* now try to match the printer name against the [Devices] section */
899*593dc095SDavid du Colombier if ((devices = gs_malloc(wdev->memory, 4096, 1, "win_pr2_getdc")) == (char *)NULL)
9007dd7cddfSDavid du Colombier return FALSE;
9017dd7cddfSDavid du Colombier GetProfileString("Devices", NULL, "", devices, 4096);
9027dd7cddfSDavid du Colombier p = devices;
9037dd7cddfSDavid du Colombier while (*p) {
9047dd7cddfSDavid du Colombier if (stricmp(p, device) == 0)
9057dd7cddfSDavid du Colombier break;
9067dd7cddfSDavid du Colombier p += strlen(p) + 1;
9077dd7cddfSDavid du Colombier }
9087dd7cddfSDavid du Colombier if (*p == '\0')
9097dd7cddfSDavid du Colombier p = NULL;
910*593dc095SDavid du Colombier gs_free(wdev->memory, devices, 4096, 1, "win_pr2_getdc");
9117dd7cddfSDavid du Colombier if (p == NULL)
9127dd7cddfSDavid du Colombier return FALSE; /* doesn't match an available printer */
9137dd7cddfSDavid du Colombier
9147dd7cddfSDavid du Colombier /* the printer exists, get the remaining information from win.ini */
9157dd7cddfSDavid du Colombier GetProfileString("Devices", device, "", driverbuf, sizeof(driverbuf));
9167dd7cddfSDavid du Colombier driver = strtok(driverbuf, ",");
9177dd7cddfSDavid du Colombier output = strtok(NULL, ",");
9187dd7cddfSDavid du Colombier if (is_win32s)
9197dd7cddfSDavid du Colombier {
9207dd7cddfSDavid du Colombier strcpy(drvname, driver);
9217dd7cddfSDavid du Colombier strcat(drvname, ".drv");
9227dd7cddfSDavid du Colombier driver = drvname;
9237dd7cddfSDavid du Colombier }
9247dd7cddfSDavid du Colombier
9257dd7cddfSDavid du Colombier if (!is_win32s) { /* Win32 */
9267dd7cddfSDavid du Colombier if (!OpenPrinter(device, &hprinter, NULL))
9277dd7cddfSDavid du Colombier return FALSE;
9287dd7cddfSDavid du Colombier size = DocumentProperties(NULL, hprinter, device, NULL, NULL, 0);
929*593dc095SDavid du Colombier if ((podevmode = gs_malloc(wdev->memory, size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) {
9307dd7cddfSDavid du Colombier ClosePrinter(hprinter);
9317dd7cddfSDavid du Colombier return FALSE;
9327dd7cddfSDavid du Colombier }
933*593dc095SDavid du Colombier if ((pidevmode = gs_malloc(wdev->memory, size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) {
934*593dc095SDavid du Colombier gs_free(wdev->memory, podevmode, size, 1, "win_pr2_getdc");
9357dd7cddfSDavid du Colombier ClosePrinter(hprinter);
9367dd7cddfSDavid du Colombier return FALSE;
9377dd7cddfSDavid du Colombier }
9387dd7cddfSDavid du Colombier DocumentProperties(NULL, hprinter, device, podevmode, NULL, DM_OUT_BUFFER);
9397dd7cddfSDavid du Colombier pfnDeviceCapabilities = (LPFNDEVCAPS) DeviceCapabilities;
9407dd7cddfSDavid du Colombier } else
9417dd7cddfSDavid du Colombier { /* Win16 and Win32s */
9427dd7cddfSDavid du Colombier /* now load the printer driver */
9437dd7cddfSDavid du Colombier hlib = LoadLibrary(driver);
9447dd7cddfSDavid du Colombier if (hlib < (HINSTANCE) HINSTANCE_ERROR)
9457dd7cddfSDavid du Colombier return FALSE;
9467dd7cddfSDavid du Colombier
9477dd7cddfSDavid du Colombier /* call ExtDeviceMode() to get default parameters */
9487dd7cddfSDavid du Colombier pfnExtDeviceMode = (LPFNDEVMODE) GetProcAddress(hlib, "ExtDeviceMode");
9497dd7cddfSDavid du Colombier if (pfnExtDeviceMode == (LPFNDEVMODE) NULL) {
9507dd7cddfSDavid du Colombier FreeLibrary(hlib);
9517dd7cddfSDavid du Colombier return FALSE;
9527dd7cddfSDavid du Colombier }
9537dd7cddfSDavid du Colombier pfnDeviceCapabilities = (LPFNDEVCAPS) GetProcAddress(hlib, "DeviceCapabilities");
9547dd7cddfSDavid du Colombier if (pfnDeviceCapabilities == (LPFNDEVCAPS) NULL) {
9557dd7cddfSDavid du Colombier FreeLibrary(hlib);
9567dd7cddfSDavid du Colombier return FALSE;
9577dd7cddfSDavid du Colombier }
9587dd7cddfSDavid du Colombier size = pfnExtDeviceMode(NULL, hlib, NULL, device, output, NULL, NULL, 0);
959*593dc095SDavid du Colombier if ((podevmode = gs_malloc(wdev->memory, size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) {
9607dd7cddfSDavid du Colombier FreeLibrary(hlib);
9617dd7cddfSDavid du Colombier return FALSE;
9627dd7cddfSDavid du Colombier }
963*593dc095SDavid du Colombier if ((pidevmode = gs_malloc(wdev->memory, size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) {
964*593dc095SDavid du Colombier gs_free(wdev->memory, podevmode, size, 1, "win_pr2_getdc");
9657dd7cddfSDavid du Colombier FreeLibrary(hlib);
9667dd7cddfSDavid du Colombier return FALSE;
9677dd7cddfSDavid du Colombier }
9687dd7cddfSDavid du Colombier pfnExtDeviceMode(NULL, hlib, podevmode, device, output,
9697dd7cddfSDavid du Colombier NULL, NULL, DM_OUT_BUFFER);
9707dd7cddfSDavid du Colombier }
9717dd7cddfSDavid du Colombier
9727dd7cddfSDavid du Colombier /* now find out what paper sizes are available */
9737dd7cddfSDavid du Colombier devcapsize = pfnDeviceCapabilities(device, output, DC_PAPERSIZE, NULL, NULL);
9747dd7cddfSDavid du Colombier devcapsize *= sizeof(POINT);
975*593dc095SDavid du Colombier if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
9767dd7cddfSDavid du Colombier return FALSE;
9777dd7cddfSDavid du Colombier n = pfnDeviceCapabilities(device, output, DC_PAPERSIZE, devcap, NULL);
9787dd7cddfSDavid du Colombier paperwidth = (int)(wdev->MediaSize[0] * 254 / 72);
9797dd7cddfSDavid du Colombier paperheight = (int)(wdev->MediaSize[1] * 254 / 72);
9807dd7cddfSDavid du Colombier papername[0] = '\0';
9817dd7cddfSDavid du Colombier papersize = 0;
9827dd7cddfSDavid du Colombier paperindex = -1;
9837dd7cddfSDavid du Colombier orientation = 0;
9847dd7cddfSDavid du Colombier pp = (POINT *) devcap;
9857dd7cddfSDavid du Colombier for (i = 0; i < n; i++, pp++) {
9867dd7cddfSDavid du Colombier if ((pp->x < paperwidth + 20) && (pp->x > paperwidth - 20) &&
9877dd7cddfSDavid du Colombier (pp->y < paperheight + 20) && (pp->y > paperheight - 20)) {
9887dd7cddfSDavid du Colombier paperindex = i;
9897dd7cddfSDavid du Colombier paperwidth = pp->x;
9907dd7cddfSDavid du Colombier paperheight = pp->y;
9917dd7cddfSDavid du Colombier orientation = DMORIENT_PORTRAIT;
9927dd7cddfSDavid du Colombier break;
9937dd7cddfSDavid du Colombier }
9947dd7cddfSDavid du Colombier }
9957dd7cddfSDavid du Colombier if (paperindex < 0) {
9967dd7cddfSDavid du Colombier /* try again in landscape */
9977dd7cddfSDavid du Colombier pp = (POINT *) devcap;
9987dd7cddfSDavid du Colombier for (i = 0; i < n; i++, pp++) {
9997dd7cddfSDavid du Colombier if ((pp->x < paperheight + 20) && (pp->x > paperheight - 20) &&
10007dd7cddfSDavid du Colombier (pp->y < paperwidth + 20) && (pp->y > paperwidth - 20)) {
10017dd7cddfSDavid du Colombier paperindex = i;
10027dd7cddfSDavid du Colombier paperwidth = pp->x;
10037dd7cddfSDavid du Colombier paperheight = pp->y;
10047dd7cddfSDavid du Colombier orientation = DMORIENT_LANDSCAPE;
10057dd7cddfSDavid du Colombier break;
10067dd7cddfSDavid du Colombier }
10077dd7cddfSDavid du Colombier }
10087dd7cddfSDavid du Colombier }
1009*593dc095SDavid du Colombier gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");
10107dd7cddfSDavid du Colombier
10117dd7cddfSDavid du Colombier /* get the dmPaperSize */
10127dd7cddfSDavid du Colombier devcapsize = pfnDeviceCapabilities(device, output, DC_PAPERS, NULL, NULL);
10137dd7cddfSDavid du Colombier devcapsize *= sizeof(WORD);
1014*593dc095SDavid du Colombier if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
10157dd7cddfSDavid du Colombier return FALSE;
10167dd7cddfSDavid du Colombier n = pfnDeviceCapabilities(device, output, DC_PAPERS, devcap, NULL);
10177dd7cddfSDavid du Colombier if ((paperindex >= 0) && (paperindex < n))
10187dd7cddfSDavid du Colombier papersize = ((WORD *) devcap)[paperindex];
1019*593dc095SDavid du Colombier gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");
10207dd7cddfSDavid du Colombier
10217dd7cddfSDavid du Colombier /* get the paper name */
10227dd7cddfSDavid du Colombier devcapsize = pfnDeviceCapabilities(device, output, DC_PAPERNAMES, NULL, NULL);
10237dd7cddfSDavid du Colombier devcapsize *= 64;
1024*593dc095SDavid du Colombier if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
10257dd7cddfSDavid du Colombier return FALSE;
10267dd7cddfSDavid du Colombier n = pfnDeviceCapabilities(device, output, DC_PAPERNAMES, devcap, NULL);
10277dd7cddfSDavid du Colombier if ((paperindex >= 0) && (paperindex < n))
10287dd7cddfSDavid du Colombier strcpy(papername, devcap + paperindex * 64);
1029*593dc095SDavid du Colombier gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");
10307dd7cddfSDavid du Colombier
10317dd7cddfSDavid du Colombier memcpy(pidevmode, podevmode, size);
10327dd7cddfSDavid du Colombier
10337dd7cddfSDavid du Colombier pidevmode->dmFields = 0;
10347dd7cddfSDavid du Colombier
10357dd7cddfSDavid du Colombier wdev->paper_name[0] = 0;
10367dd7cddfSDavid du Colombier
10377dd7cddfSDavid du Colombier if ( (wdev->user_paper)
10387dd7cddfSDavid du Colombier && (wdev->user_paper != papersize) ) {
10397dd7cddfSDavid du Colombier papersize = wdev->user_paper;
10407dd7cddfSDavid du Colombier paperheight = 0;
10417dd7cddfSDavid du Colombier paperwidth = 0;
10427dd7cddfSDavid du Colombier papername[0] = 0;
10437dd7cddfSDavid du Colombier }
10447dd7cddfSDavid du Colombier if (wdev->user_orient) {
10457dd7cddfSDavid du Colombier orientation = wdev->user_orient;
10467dd7cddfSDavid du Colombier }
10477dd7cddfSDavid du Colombier
10487dd7cddfSDavid du Colombier pidevmode->dmFields &= ~(DM_PAPERSIZE | DM_ORIENTATION | DM_COLOR | DM_PAPERLENGTH | DM_PAPERWIDTH | DM_DUPLEX);
10497dd7cddfSDavid du Colombier pidevmode->dmFields |= DM_DEFAULTSOURCE;
10507dd7cddfSDavid du Colombier pidevmode->dmDefaultSource = 0;
10517dd7cddfSDavid du Colombier
10527dd7cddfSDavid du Colombier if (orientation) {
10537dd7cddfSDavid du Colombier wdev->user_orient = orientation;
10547dd7cddfSDavid du Colombier }
10557dd7cddfSDavid du Colombier if (papersize) {
10567dd7cddfSDavid du Colombier wdev->user_paper = papersize;
10577dd7cddfSDavid du Colombier strcpy (wdev->paper_name, papername);
10587dd7cddfSDavid du Colombier }
10597dd7cddfSDavid du Colombier
10607dd7cddfSDavid du Colombier if (paperheight && paperwidth) {
10617dd7cddfSDavid du Colombier pidevmode->dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH);
10627dd7cddfSDavid du Colombier pidevmode->dmPaperWidth = paperwidth;
10637dd7cddfSDavid du Colombier pidevmode->dmPaperLength = paperheight;
10647dd7cddfSDavid du Colombier wdev->user_media_size[0] = paperwidth / 254.0 * 72.0;
10657dd7cddfSDavid du Colombier wdev->user_media_size[1] = paperheight / 254.0 * 72.0;
10667dd7cddfSDavid du Colombier }
10677dd7cddfSDavid du Colombier
10687dd7cddfSDavid du Colombier if (DeviceCapabilities(device, output, DC_DUPLEX, NULL, NULL)) {
10697dd7cddfSDavid du Colombier wdev->Duplex_set = 1;
10707dd7cddfSDavid du Colombier }
10717dd7cddfSDavid du Colombier
10727dd7cddfSDavid du Colombier win_pr2_update_win(wdev, pidevmode);
10737dd7cddfSDavid du Colombier
10747dd7cddfSDavid du Colombier if (!is_win32s) {
10757dd7cddfSDavid du Colombier
10767dd7cddfSDavid du Colombier /* merge the entries */
10777dd7cddfSDavid du Colombier DocumentProperties(NULL, hprinter, device, podevmode, pidevmode, DM_IN_BUFFER | DM_OUT_BUFFER);
10787dd7cddfSDavid du Colombier ClosePrinter(hprinter);
10797dd7cddfSDavid du Colombier
10807dd7cddfSDavid du Colombier /* now get a DC */
10817dd7cddfSDavid du Colombier wdev->hdcprn = CreateDC(driver, device, NULL, podevmode);
10827dd7cddfSDavid du Colombier } else
10837dd7cddfSDavid du Colombier { /* Win16 and Win32s */
10847dd7cddfSDavid du Colombier pfnExtDeviceMode(NULL, hlib, podevmode, device, output,
10857dd7cddfSDavid du Colombier pidevmode, NULL, DM_IN_BUFFER | DM_OUT_BUFFER);
10867dd7cddfSDavid du Colombier /* release the printer driver */
10877dd7cddfSDavid du Colombier FreeLibrary(hlib);
10887dd7cddfSDavid du Colombier /* now get a DC */
10897dd7cddfSDavid du Colombier if (is_win32s)
10907dd7cddfSDavid du Colombier strtok(driver, "."); /* remove .drv */
10917dd7cddfSDavid du Colombier wdev->hdcprn = CreateDC(driver, device, output, podevmode);
10927dd7cddfSDavid du Colombier }
10937dd7cddfSDavid du Colombier
10947dd7cddfSDavid du Colombier if (wdev->win32_hdevmode == NULL) {
10957dd7cddfSDavid du Colombier wdev->win32_hdevmode = GlobalAlloc(0, sizeof(DEVMODE));
10967dd7cddfSDavid du Colombier }
10977dd7cddfSDavid du Colombier
10987dd7cddfSDavid du Colombier if (wdev->win32_hdevmode) {
1099*593dc095SDavid du Colombier LPDEVMODE pdevmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
11007dd7cddfSDavid du Colombier if (pdevmode) {
11017dd7cddfSDavid du Colombier memcpy(pdevmode, podevmode, sizeof(DEVMODE));
11027dd7cddfSDavid du Colombier GlobalUnlock(wdev->win32_hdevmode);
11037dd7cddfSDavid du Colombier }
11047dd7cddfSDavid du Colombier }
11057dd7cddfSDavid du Colombier
1106*593dc095SDavid du Colombier gs_free(wdev->memory, pidevmode, size, 1, "win_pr2_getdc");
1107*593dc095SDavid du Colombier gs_free(wdev->memory, podevmode, size, 1, "win_pr2_getdc");
11087dd7cddfSDavid du Colombier
11097dd7cddfSDavid du Colombier if (wdev->hdcprn != (HDC) NULL)
11107dd7cddfSDavid du Colombier return TRUE; /* success */
11117dd7cddfSDavid du Colombier
11127dd7cddfSDavid du Colombier /* fall back to prompting user */
11137dd7cddfSDavid du Colombier return FALSE;
11147dd7cddfSDavid du Colombier }
11157dd7cddfSDavid du Colombier
11167dd7cddfSDavid du Colombier
11177dd7cddfSDavid du Colombier /*
11187dd7cddfSDavid du Colombier * Minimalist update of the wdev parameters (mainly for the
11197dd7cddfSDavid du Colombier * UserSettings parameters).
11207dd7cddfSDavid du Colombier */
11217dd7cddfSDavid du Colombier
11227dd7cddfSDavid du Colombier private int
win_pr2_update_dev(gx_device_win_pr2 * dev,LPDEVMODE pdevmode)11237dd7cddfSDavid du Colombier win_pr2_update_dev(gx_device_win_pr2 * dev, LPDEVMODE pdevmode)
11247dd7cddfSDavid du Colombier {
11257dd7cddfSDavid du Colombier if (pdevmode == 0)
11267dd7cddfSDavid du Colombier return FALSE;
11277dd7cddfSDavid du Colombier
11287dd7cddfSDavid du Colombier if (pdevmode->dmFields & DM_COLOR) {
11297dd7cddfSDavid du Colombier dev->user_color = pdevmode->dmColor;
11307dd7cddfSDavid du Colombier }
11317dd7cddfSDavid du Colombier if (pdevmode->dmFields & DM_ORIENTATION) {
11327dd7cddfSDavid du Colombier dev->user_orient = pdevmode->dmOrientation;
11337dd7cddfSDavid du Colombier }
11347dd7cddfSDavid du Colombier if (pdevmode->dmFields & DM_PAPERSIZE) {
11357dd7cddfSDavid du Colombier dev->user_paper = pdevmode->dmPaperSize;
11367dd7cddfSDavid du Colombier dev->user_media_size[0] = pdevmode->dmPaperWidth / 254.0 * 72.0;
11377dd7cddfSDavid du Colombier dev->user_media_size[1] = pdevmode->dmPaperLength / 254.0 * 72.0;
11387dd7cddfSDavid du Colombier dev->paper_name[0] = 0; /* unknown paper size */
11397dd7cddfSDavid du Colombier }
11407dd7cddfSDavid du Colombier if (pdevmode->dmFields & DM_DUPLEX) {
11417dd7cddfSDavid du Colombier dev->Duplex_set = 1;
11427dd7cddfSDavid du Colombier dev->Duplex = pdevmode->dmDuplex == DMDUP_SIMPLEX ? false : true;
11433ff48bf5SDavid du Colombier dev->tumble = pdevmode->dmDuplex == DMDUP_HORIZONTAL ? true : false;
11447dd7cddfSDavid du Colombier }
11457dd7cddfSDavid du Colombier
11467dd7cddfSDavid du Colombier return TRUE;
11477dd7cddfSDavid du Colombier }
11487dd7cddfSDavid du Colombier
11497dd7cddfSDavid du Colombier private int
win_pr2_update_win(gx_device_win_pr2 * dev,LPDEVMODE pdevmode)11507dd7cddfSDavid du Colombier win_pr2_update_win(gx_device_win_pr2 * dev, LPDEVMODE pdevmode)
11517dd7cddfSDavid du Colombier {
11527dd7cddfSDavid du Colombier if (dev->Duplex_set > 0) {
11537dd7cddfSDavid du Colombier pdevmode->dmFields |= DM_DUPLEX;
11547dd7cddfSDavid du Colombier pdevmode->dmDuplex = DMDUP_SIMPLEX;
11557dd7cddfSDavid du Colombier if (dev->Duplex) {
11563ff48bf5SDavid du Colombier if (dev->tumble == false) {
11577dd7cddfSDavid du Colombier pdevmode->dmDuplex = DMDUP_VERTICAL;
11583ff48bf5SDavid du Colombier } else {
11597dd7cddfSDavid du Colombier pdevmode->dmDuplex = DMDUP_HORIZONTAL;
11607dd7cddfSDavid du Colombier }
11617dd7cddfSDavid du Colombier }
11627dd7cddfSDavid du Colombier }
11637dd7cddfSDavid du Colombier
11647dd7cddfSDavid du Colombier if (dev->user_color) {
11657dd7cddfSDavid du Colombier pdevmode->dmColor = dev->user_color;
11667dd7cddfSDavid du Colombier pdevmode->dmFields |= DM_COLOR;
11677dd7cddfSDavid du Colombier }
11687dd7cddfSDavid du Colombier
11697dd7cddfSDavid du Colombier if (dev->user_orient) {
11707dd7cddfSDavid du Colombier pdevmode->dmFields |= DM_ORIENTATION;
11717dd7cddfSDavid du Colombier pdevmode->dmOrientation = dev->user_orient;
11727dd7cddfSDavid du Colombier }
11737dd7cddfSDavid du Colombier
11747dd7cddfSDavid du Colombier if (dev->user_paper) {
11757dd7cddfSDavid du Colombier pdevmode->dmFields |= DM_PAPERSIZE;
11767dd7cddfSDavid du Colombier pdevmode->dmPaperSize = dev->user_paper;
11777dd7cddfSDavid du Colombier }
11783ff48bf5SDavid du Colombier return 0;
11797dd7cddfSDavid du Colombier }
11807dd7cddfSDavid du Colombier
11817dd7cddfSDavid du Colombier /********************************************************************************/
11827dd7cddfSDavid du Colombier
11837dd7cddfSDavid du Colombier #define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
11847dd7cddfSDavid du Colombier switch ( code = pread(dict.list, (param_name = pname), &(pa)) )\
11857dd7cddfSDavid du Colombier {\
11867dd7cddfSDavid du Colombier case 0:\
11877dd7cddfSDavid du Colombier if ( (pa).size != psize )\
11887dd7cddfSDavid du Colombier ecode = gs_note_error(gs_error_rangecheck);\
11897dd7cddfSDavid du Colombier else {
11907dd7cddfSDavid du Colombier /* The body of the processing code goes here. */
11917dd7cddfSDavid du Colombier /* If it succeeds, it should do a 'break'; */
11927dd7cddfSDavid du Colombier /* if it fails, it should set ecode and fall through. */
11937dd7cddfSDavid du Colombier #define END_ARRAY_PARAM(pa, e)\
11947dd7cddfSDavid du Colombier }\
11957dd7cddfSDavid du Colombier goto e;\
11967dd7cddfSDavid du Colombier default:\
11977dd7cddfSDavid du Colombier ecode = code;\
11987dd7cddfSDavid du Colombier e: param_signal_error(dict.list, param_name, ecode);\
11997dd7cddfSDavid du Colombier case 1:\
12007dd7cddfSDavid du Colombier (pa).data = 0; /* mark as not filled */\
12017dd7cddfSDavid du Colombier }
12027dd7cddfSDavid du Colombier
12037dd7cddfSDavid du Colombier
12047dd7cddfSDavid du Colombier /* Put the user params from UserSettings into our */
12057dd7cddfSDavid du Colombier /* internal variables. */
12067dd7cddfSDavid du Colombier private int
win_pr2_read_user_settings(gx_device_win_pr2 * wdev,gs_param_list * plist)12077dd7cddfSDavid du Colombier win_pr2_read_user_settings(gx_device_win_pr2 * wdev, gs_param_list * plist)
12087dd7cddfSDavid du Colombier {
12097dd7cddfSDavid du Colombier gs_param_dict dict;
12107dd7cddfSDavid du Colombier gs_param_string docn = { 0 };
12117dd7cddfSDavid du Colombier const char* dict_name = "UserSettings";
12127dd7cddfSDavid du Colombier const char* param_name = "";
12137dd7cddfSDavid du Colombier int code = 0;
12147dd7cddfSDavid du Colombier int ecode = 0;
12157dd7cddfSDavid du Colombier
12167dd7cddfSDavid du Colombier switch (code = param_begin_read_dict(plist, dict_name, &dict, false)) {
12177dd7cddfSDavid du Colombier default:
12187dd7cddfSDavid du Colombier param_signal_error(plist, dict_name, code);
12197dd7cddfSDavid du Colombier return code;
12207dd7cddfSDavid du Colombier case 1:
12217dd7cddfSDavid du Colombier break;
12227dd7cddfSDavid du Colombier case 0:
12237dd7cddfSDavid du Colombier {
12247dd7cddfSDavid du Colombier gs_param_int_array ia;
12257dd7cddfSDavid du Colombier
12267dd7cddfSDavid du Colombier BEGIN_ARRAY_PARAM(param_read_int_array, "DocumentRange", ia, 2, ia)
12277dd7cddfSDavid du Colombier if ((ia.data[0] < 0) ||
12287dd7cddfSDavid du Colombier (ia.data[1] < 0) ||
12297dd7cddfSDavid du Colombier (ia.data[0] > ia.data[1]))
12307dd7cddfSDavid du Colombier ecode = gs_note_error(gs_error_rangecheck);
12317dd7cddfSDavid du Colombier wdev->doc_page_begin = ia.data[0];
12327dd7cddfSDavid du Colombier wdev->doc_page_end = ia.data[1];
12337dd7cddfSDavid du Colombier END_ARRAY_PARAM(ia, doc_range_error)
12347dd7cddfSDavid du Colombier
12357dd7cddfSDavid du Colombier BEGIN_ARRAY_PARAM(param_read_int_array, "SelectedRange", ia, 2, ia)
12367dd7cddfSDavid du Colombier if ((ia.data[0] < 0) ||
12377dd7cddfSDavid du Colombier (ia.data[1] < 0) ||
12387dd7cddfSDavid du Colombier (ia.data[0] > ia.data[1]))
12397dd7cddfSDavid du Colombier ecode = gs_note_error(gs_error_rangecheck);
12407dd7cddfSDavid du Colombier wdev->user_page_begin = ia.data[0];
12417dd7cddfSDavid du Colombier wdev->user_page_end = ia.data[1];
12427dd7cddfSDavid du Colombier END_ARRAY_PARAM(ia, sel_range_error)
12437dd7cddfSDavid du Colombier
12447dd7cddfSDavid du Colombier param_read_int(dict.list, "Copies", &wdev->user_copies);
12457dd7cddfSDavid du Colombier param_read_int(dict.list, "Paper", &wdev->user_paper);
12467dd7cddfSDavid du Colombier param_read_int(dict.list, "Orientation", &wdev->user_orient);
12477dd7cddfSDavid du Colombier param_read_int(dict.list, "Color", &wdev->user_color);
12487dd7cddfSDavid du Colombier param_read_int(dict.list, "MaxResolution", &wdev->max_dpi);
12497dd7cddfSDavid du Colombier
12507dd7cddfSDavid du Colombier switch (code = param_read_string(dict.list, (param_name = "DocumentName"), &docn)) {
12517dd7cddfSDavid du Colombier case 0:
12527dd7cddfSDavid du Colombier if (docn.size < sizeof(wdev->doc_name))
12537dd7cddfSDavid du Colombier break;
12547dd7cddfSDavid du Colombier code = gs_error_rangecheck;
12557dd7cddfSDavid du Colombier /* fall through */
12567dd7cddfSDavid du Colombier default:
12577dd7cddfSDavid du Colombier ecode = code;
12587dd7cddfSDavid du Colombier param_signal_error(plist, param_name, ecode);
12597dd7cddfSDavid du Colombier /* fall through */
12607dd7cddfSDavid du Colombier case 1:
12617dd7cddfSDavid du Colombier docn.data = 0;
12627dd7cddfSDavid du Colombier break;
12637dd7cddfSDavid du Colombier }
12647dd7cddfSDavid du Colombier
12657dd7cddfSDavid du Colombier param_end_read_dict(plist, dict_name, &dict);
12667dd7cddfSDavid du Colombier
12677dd7cddfSDavid du Colombier if (docn.data) {
12687dd7cddfSDavid du Colombier memcpy(wdev->doc_name, docn.data, docn.size);
12697dd7cddfSDavid du Colombier wdev->doc_name[docn.size] = 0;
12707dd7cddfSDavid du Colombier }
12717dd7cddfSDavid du Colombier
12727dd7cddfSDavid du Colombier wdev->print_copies = 1;
12737dd7cddfSDavid du Colombier
12747dd7cddfSDavid du Colombier if (wdev->win32_hdevmode) {
12757dd7cddfSDavid du Colombier LPDEVMODE devmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
12767dd7cddfSDavid du Colombier if (devmode) {
12777dd7cddfSDavid du Colombier devmode->dmCopies = wdev->user_copies;
12787dd7cddfSDavid du Colombier devmode->dmPaperSize = wdev->user_paper;
12797dd7cddfSDavid du Colombier devmode->dmOrientation = wdev->user_orient;
12807dd7cddfSDavid du Colombier devmode->dmColor = wdev->user_color;
12817dd7cddfSDavid du Colombier GlobalUnlock(wdev->win32_hdevmode);
12827dd7cddfSDavid du Colombier }
12837dd7cddfSDavid du Colombier }
12847dd7cddfSDavid du Colombier }
12857dd7cddfSDavid du Colombier break;
12867dd7cddfSDavid du Colombier }
12877dd7cddfSDavid du Colombier
12887dd7cddfSDavid du Colombier return code;
12897dd7cddfSDavid du Colombier }
12907dd7cddfSDavid du Colombier
12917dd7cddfSDavid du Colombier
12927dd7cddfSDavid du Colombier private int
win_pr2_write_user_settings(gx_device_win_pr2 * wdev,gs_param_list * plist)12937dd7cddfSDavid du Colombier win_pr2_write_user_settings(gx_device_win_pr2 * wdev, gs_param_list * plist)
12947dd7cddfSDavid du Colombier {
12957dd7cddfSDavid du Colombier gs_param_dict dict;
12967dd7cddfSDavid du Colombier gs_param_int_array range;
12977dd7cddfSDavid du Colombier gs_param_float_array box;
12987dd7cddfSDavid du Colombier gs_param_string docn;
12997dd7cddfSDavid du Colombier gs_param_string papn;
13007dd7cddfSDavid du Colombier int array[2];
13017dd7cddfSDavid du Colombier const char* pname = "UserSettings";
13027dd7cddfSDavid du Colombier int code;
13037dd7cddfSDavid du Colombier
13047dd7cddfSDavid du Colombier dict.size = 12;
13057dd7cddfSDavid du Colombier code = param_begin_write_dict(plist, pname, &dict, false);
13067dd7cddfSDavid du Colombier if (code < 0) return code;
13077dd7cddfSDavid du Colombier
13087dd7cddfSDavid du Colombier array[0] = wdev->doc_page_begin;
13097dd7cddfSDavid du Colombier array[1] = wdev->doc_page_end;
13107dd7cddfSDavid du Colombier range.data = array;
13117dd7cddfSDavid du Colombier range.size = 2;
13127dd7cddfSDavid du Colombier range.persistent = false;
13137dd7cddfSDavid du Colombier code = param_write_int_array(dict.list, "DocumentRange", &range);
13147dd7cddfSDavid du Colombier if (code < 0) goto error;
13157dd7cddfSDavid du Colombier
13167dd7cddfSDavid du Colombier array[0] = wdev->user_page_begin;
13177dd7cddfSDavid du Colombier array[1] = wdev->user_page_end;
13187dd7cddfSDavid du Colombier range.data = array;
13197dd7cddfSDavid du Colombier range.size = 2;
13207dd7cddfSDavid du Colombier range.persistent = false;
13217dd7cddfSDavid du Colombier code = param_write_int_array(dict.list, "SelectedRange", &range);
13227dd7cddfSDavid du Colombier if (code < 0) goto error;
13237dd7cddfSDavid du Colombier
13247dd7cddfSDavid du Colombier box.data = wdev->user_media_size;
13257dd7cddfSDavid du Colombier box.size = 2;
13267dd7cddfSDavid du Colombier box.persistent = false;
13277dd7cddfSDavid du Colombier code = param_write_float_array(dict.list, "MediaSize", &box);
13287dd7cddfSDavid du Colombier if (code < 0) goto error;
13297dd7cddfSDavid du Colombier
13307dd7cddfSDavid du Colombier code = param_write_int(dict.list, "Copies", &wdev->user_copies);
13317dd7cddfSDavid du Colombier if (code < 0) goto error;
13327dd7cddfSDavid du Colombier
13337dd7cddfSDavid du Colombier code = param_write_int(dict.list, "Paper", &wdev->user_paper);
13347dd7cddfSDavid du Colombier if (code < 0) goto error;
13357dd7cddfSDavid du Colombier
13367dd7cddfSDavid du Colombier code = param_write_int(dict.list, "Orientation", &wdev->user_orient);
13377dd7cddfSDavid du Colombier if (code < 0) goto error;
13387dd7cddfSDavid du Colombier
13397dd7cddfSDavid du Colombier code = param_write_int(dict.list, "Color", &wdev->user_color);
13407dd7cddfSDavid du Colombier if (code < 0) goto error;
13417dd7cddfSDavid du Colombier
13427dd7cddfSDavid du Colombier code = param_write_int(dict.list, "MaxResolution", &wdev->max_dpi);
13437dd7cddfSDavid du Colombier if (code < 0) goto error;
13447dd7cddfSDavid du Colombier
13457dd7cddfSDavid du Colombier code = param_write_int(dict.list, "PrintCopies", &wdev->print_copies);
13467dd7cddfSDavid du Colombier if (code < 0) goto error;
13477dd7cddfSDavid du Colombier
13487dd7cddfSDavid du Colombier docn.data = (const byte*)wdev->doc_name;
13497dd7cddfSDavid du Colombier docn.size = strlen(wdev->doc_name);
13507dd7cddfSDavid du Colombier docn.persistent = false;
13517dd7cddfSDavid du Colombier
13527dd7cddfSDavid du Colombier code = param_write_string(dict.list, "DocumentName", &docn);
13537dd7cddfSDavid du Colombier if (code < 0) goto error;
13547dd7cddfSDavid du Colombier
13557dd7cddfSDavid du Colombier papn.data = (const byte*)wdev->paper_name;
13567dd7cddfSDavid du Colombier papn.size = strlen(wdev->paper_name);
13577dd7cddfSDavid du Colombier papn.persistent = false;
13587dd7cddfSDavid du Colombier
13597dd7cddfSDavid du Colombier code = param_write_string(dict.list, "PaperName", &papn);
13607dd7cddfSDavid du Colombier if (code < 0) goto error;
13617dd7cddfSDavid du Colombier
13627dd7cddfSDavid du Colombier code = param_write_bool(dict.list, "UserChangedSettings", &wdev->user_changed_settings);
13637dd7cddfSDavid du Colombier
13647dd7cddfSDavid du Colombier error:
13657dd7cddfSDavid du Colombier param_end_write_dict(plist, pname, &dict);
13667dd7cddfSDavid du Colombier return code;
13677dd7cddfSDavid du Colombier }
13687dd7cddfSDavid du Colombier
13697dd7cddfSDavid du Colombier /********************************************************************************/
13707dd7cddfSDavid du Colombier
13717dd7cddfSDavid du Colombier /* Show up a dialog for the user to choose a printer and a paper size.
13727dd7cddfSDavid du Colombier * If mode == 3, then automatically select the default Windows printer
13737dd7cddfSDavid du Colombier * instead of asking the user.
13747dd7cddfSDavid du Colombier */
13757dd7cddfSDavid du Colombier
13767dd7cddfSDavid du Colombier private int
win_pr2_print_setup_interaction(gx_device_win_pr2 * wdev,int mode)13777dd7cddfSDavid du Colombier win_pr2_print_setup_interaction(gx_device_win_pr2 * wdev, int mode)
13787dd7cddfSDavid du Colombier {
13797dd7cddfSDavid du Colombier PRINTDLG pd;
13807dd7cddfSDavid du Colombier LPDEVMODE devmode;
13817dd7cddfSDavid du Colombier LPDEVNAMES devnames;
13827dd7cddfSDavid du Colombier
13837dd7cddfSDavid du Colombier wdev->user_changed_settings = FALSE;
13843ff48bf5SDavid du Colombier wdev->query_user = mode;
13857dd7cddfSDavid du Colombier
13867dd7cddfSDavid du Colombier memset(&pd, 0, sizeof(pd));
13877dd7cddfSDavid du Colombier pd.lStructSize = sizeof(pd);
13883ff48bf5SDavid du Colombier pd.hwndOwner = PARENT_WINDOW;
13897dd7cddfSDavid du Colombier
13907dd7cddfSDavid du Colombier switch (mode) {
13917dd7cddfSDavid du Colombier case 2: pd.Flags = PD_PRINTSETUP; break;
13927dd7cddfSDavid du Colombier case 3: pd.Flags = PD_RETURNDEFAULT; break;
13937dd7cddfSDavid du Colombier default: pd.Flags = 0; break;
13947dd7cddfSDavid du Colombier }
13957dd7cddfSDavid du Colombier
13967dd7cddfSDavid du Colombier pd.Flags |= PD_USEDEVMODECOPIES;
13977dd7cddfSDavid du Colombier
13987dd7cddfSDavid du Colombier pd.nMinPage = wdev->doc_page_begin;
13997dd7cddfSDavid du Colombier pd.nMaxPage = wdev->doc_page_end;
14007dd7cddfSDavid du Colombier pd.nFromPage = wdev->user_page_begin;
14017dd7cddfSDavid du Colombier pd.nToPage = wdev->user_page_end;
14027dd7cddfSDavid du Colombier pd.nCopies = wdev->user_copies;
14037dd7cddfSDavid du Colombier
14047dd7cddfSDavid du Colombier /* Show the Print Setup dialog and let the user choose a printer
14057dd7cddfSDavid du Colombier * and a paper size/orientation.
14067dd7cddfSDavid du Colombier */
14077dd7cddfSDavid du Colombier
14087dd7cddfSDavid du Colombier if (!PrintDlg(&pd)) return FALSE;
14097dd7cddfSDavid du Colombier
14107dd7cddfSDavid du Colombier devmode = (LPDEVMODE) GlobalLock(pd.hDevMode);
14117dd7cddfSDavid du Colombier devnames = (LPDEVNAMES) GlobalLock(pd.hDevNames);
14127dd7cddfSDavid du Colombier
14137dd7cddfSDavid du Colombier wdev->user_changed_settings = TRUE;
14143ff48bf5SDavid du Colombier if (wdev->use_old_spool_name) {
14157dd7cddfSDavid du Colombier sprintf(wdev->fname, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset));
14163ff48bf5SDavid du Colombier } else {
14173ff48bf5SDavid du Colombier sprintf(wdev->fname, "%%printer%%%s", (char*)(devnames)+(devnames->wDeviceOffset));
14183ff48bf5SDavid du Colombier }
14197dd7cddfSDavid du Colombier
14207dd7cddfSDavid du Colombier if (mode == 3) {
14217dd7cddfSDavid du Colombier devmode->dmCopies = wdev->user_copies * wdev->print_copies;
14227dd7cddfSDavid du Colombier pd.nCopies = 1;
14237dd7cddfSDavid du Colombier }
14247dd7cddfSDavid du Colombier
14257dd7cddfSDavid du Colombier wdev->user_page_begin = pd.nFromPage;
14267dd7cddfSDavid du Colombier wdev->user_page_end = pd.nToPage;
14277dd7cddfSDavid du Colombier wdev->user_copies = devmode->dmCopies;
14287dd7cddfSDavid du Colombier wdev->print_copies = pd.nCopies;
14297dd7cddfSDavid du Colombier wdev->user_media_size[0] = devmode->dmPaperWidth / 254.0 * 72.0;
14307dd7cddfSDavid du Colombier wdev->user_media_size[1] = devmode->dmPaperLength / 254.0 * 72.0;
14317dd7cddfSDavid du Colombier wdev->user_paper = devmode->dmPaperSize;
14327dd7cddfSDavid du Colombier wdev->user_orient = devmode->dmOrientation;
14337dd7cddfSDavid du Colombier wdev->user_color = devmode->dmColor;
14347dd7cddfSDavid du Colombier
14357dd7cddfSDavid du Colombier if (devmode->dmFields & DM_DUPLEX) {
14367dd7cddfSDavid du Colombier wdev->Duplex_set = 1;
14377dd7cddfSDavid du Colombier wdev->Duplex = devmode->dmDuplex == DMDUP_SIMPLEX ? false : true;
14383ff48bf5SDavid du Colombier wdev->tumble = devmode->dmDuplex == DMDUP_HORIZONTAL ? true : false;
14397dd7cddfSDavid du Colombier }
14407dd7cddfSDavid du Colombier
14417dd7cddfSDavid du Colombier {
14427dd7cddfSDavid du Colombier float xppinch = 0;
14437dd7cddfSDavid du Colombier float yppinch = 0;
14447dd7cddfSDavid du Colombier const char* driver = (char*)(devnames)+(devnames->wDriverOffset);
14457dd7cddfSDavid du Colombier const char* device = (char*)(devnames)+(devnames->wDeviceOffset);
14467dd7cddfSDavid du Colombier const char* output = (char*)(devnames)+(devnames->wOutputOffset);
14477dd7cddfSDavid du Colombier
14487dd7cddfSDavid du Colombier HDC hic = CreateIC(driver, device, output, devmode);
14497dd7cddfSDavid du Colombier
14507dd7cddfSDavid du Colombier if (hic) {
14517dd7cddfSDavid du Colombier xppinch = (float)GetDeviceCaps(hic, LOGPIXELSX);
14527dd7cddfSDavid du Colombier yppinch = (float)GetDeviceCaps(hic, LOGPIXELSY);
14537dd7cddfSDavid du Colombier wdev->user_media_size[0] = GetDeviceCaps(hic, PHYSICALWIDTH) * 72.0 / xppinch;
14547dd7cddfSDavid du Colombier wdev->user_media_size[1] = GetDeviceCaps(hic, PHYSICALHEIGHT) * 72.0 / yppinch;
14557dd7cddfSDavid du Colombier DeleteDC(hic);
14567dd7cddfSDavid du Colombier }
14577dd7cddfSDavid du Colombier }
14587dd7cddfSDavid du Colombier
14597dd7cddfSDavid du Colombier devmode = NULL;
14607dd7cddfSDavid du Colombier devnames = NULL;
14617dd7cddfSDavid du Colombier
14627dd7cddfSDavid du Colombier GlobalUnlock(pd.hDevMode);
14637dd7cddfSDavid du Colombier GlobalUnlock(pd.hDevNames);
14647dd7cddfSDavid du Colombier
14657dd7cddfSDavid du Colombier if (wdev->win32_hdevmode != NULL) {
14667dd7cddfSDavid du Colombier GlobalFree(wdev->win32_hdevmode);
14677dd7cddfSDavid du Colombier }
14687dd7cddfSDavid du Colombier if (wdev->win32_hdevnames != NULL) {
14697dd7cddfSDavid du Colombier GlobalFree(wdev->win32_hdevnames);
14707dd7cddfSDavid du Colombier }
14717dd7cddfSDavid du Colombier
14727dd7cddfSDavid du Colombier wdev->win32_hdevmode = pd.hDevMode;
14737dd7cddfSDavid du Colombier wdev->win32_hdevnames = pd.hDevNames;
14747dd7cddfSDavid du Colombier
14757dd7cddfSDavid du Colombier return TRUE;
14767dd7cddfSDavid du Colombier }
14777dd7cddfSDavid du Colombier
14787dd7cddfSDavid du Colombier /* Check that we are dealing with an original device. If this
14797dd7cddfSDavid du Colombier * happens to be a copy made by "copydevice", we will have to
14807dd7cddfSDavid du Colombier * copy the original's handles to the associated Win32 params.
14817dd7cddfSDavid du Colombier */
14827dd7cddfSDavid du Colombier
14837dd7cddfSDavid du Colombier private void
win_pr2_copy_check(gx_device_win_pr2 * wdev)14847dd7cddfSDavid du Colombier win_pr2_copy_check(gx_device_win_pr2 * wdev)
14857dd7cddfSDavid du Colombier {
14867dd7cddfSDavid du Colombier HGLOBAL hdevmode = wdev->win32_hdevmode;
14877dd7cddfSDavid du Colombier HGLOBAL hdevnames = wdev->win32_hdevnames;
14887dd7cddfSDavid du Colombier DWORD devmode_len = (hdevmode) ? GlobalSize(hdevmode) : 0;
14897dd7cddfSDavid du Colombier DWORD devnames_len = (hdevnames) ? GlobalSize(hdevnames) : 0;
14907dd7cddfSDavid du Colombier
14917dd7cddfSDavid du Colombier if (wdev->original_device == wdev)
14927dd7cddfSDavid du Colombier return;
14937dd7cddfSDavid du Colombier
14947dd7cddfSDavid du Colombier wdev->hdcprn = NULL;
14957dd7cddfSDavid du Colombier wdev->win32_hdevmode = NULL;
14967dd7cddfSDavid du Colombier wdev->win32_hdevnames = NULL;
14977dd7cddfSDavid du Colombier
14987dd7cddfSDavid du Colombier wdev->original_device = wdev;
14997dd7cddfSDavid du Colombier
15007dd7cddfSDavid du Colombier if (devmode_len) {
15017dd7cddfSDavid du Colombier wdev->win32_hdevmode = GlobalAlloc(0, devmode_len);
15027dd7cddfSDavid du Colombier if (wdev->win32_hdevmode) {
15037dd7cddfSDavid du Colombier memcpy(GlobalLock(wdev->win32_hdevmode), GlobalLock(hdevmode), devmode_len);
15047dd7cddfSDavid du Colombier GlobalUnlock(wdev->win32_hdevmode);
15057dd7cddfSDavid du Colombier GlobalUnlock(hdevmode);
15067dd7cddfSDavid du Colombier }
15077dd7cddfSDavid du Colombier }
15087dd7cddfSDavid du Colombier
15097dd7cddfSDavid du Colombier if (devnames_len) {
15107dd7cddfSDavid du Colombier wdev->win32_hdevnames = GlobalAlloc(0, devnames_len);
15117dd7cddfSDavid du Colombier if (wdev->win32_hdevnames) {
15127dd7cddfSDavid du Colombier memcpy(GlobalLock(wdev->win32_hdevnames), GlobalLock(hdevnames), devnames_len);
15137dd7cddfSDavid du Colombier GlobalUnlock(wdev->win32_hdevnames);
15147dd7cddfSDavid du Colombier GlobalUnlock(hdevnames);
15157dd7cddfSDavid du Colombier }
15167dd7cddfSDavid du Colombier }
15177dd7cddfSDavid du Colombier }
15183ff48bf5SDavid du Colombier
15193ff48bf5SDavid du Colombier
15203ff48bf5SDavid du Colombier /* Modeless dialog box - Cancel printing */
15213ff48bf5SDavid du Colombier BOOL CALLBACK
CancelDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)15223ff48bf5SDavid du Colombier CancelDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
15233ff48bf5SDavid du Colombier {
15243ff48bf5SDavid du Colombier switch (message) {
15253ff48bf5SDavid du Colombier case WM_INITDIALOG:
15263ff48bf5SDavid du Colombier SetWindowText(hDlg, szAppName);
15273ff48bf5SDavid du Colombier return TRUE;
15283ff48bf5SDavid du Colombier case WM_COMMAND:
15293ff48bf5SDavid du Colombier switch (LOWORD(wParam)) {
15303ff48bf5SDavid du Colombier case IDCANCEL:
15313ff48bf5SDavid du Colombier DestroyWindow(hDlg);
15323ff48bf5SDavid du Colombier EndDialog(hDlg, 0);
15333ff48bf5SDavid du Colombier return TRUE;
15343ff48bf5SDavid du Colombier }
15353ff48bf5SDavid du Colombier }
15363ff48bf5SDavid du Colombier return FALSE;
15373ff48bf5SDavid du Colombier }
15383ff48bf5SDavid du Colombier
15393ff48bf5SDavid du Colombier
15403ff48bf5SDavid du Colombier BOOL CALLBACK
AbortProc2(HDC hdcPrn,int code)15413ff48bf5SDavid du Colombier AbortProc2(HDC hdcPrn, int code)
15423ff48bf5SDavid du Colombier {
1543*593dc095SDavid du Colombier process_interrupts(NULL);
15443ff48bf5SDavid du Colombier if (code == SP_OUTOFDISK)
15453ff48bf5SDavid du Colombier return (FALSE); /* cancel job */
15463ff48bf5SDavid du Colombier return (TRUE);
15473ff48bf5SDavid du Colombier }
15483ff48bf5SDavid du Colombier
1549