12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532 |
- /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved.
-
- This file is part of AFPL Ghostscript.
-
- AFPL 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 Free Public License (the
- "License") for full details.
-
- Every copy of AFPL 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 AFPL 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.
- */
- /*$Id: gdevwpr2.c,v 1.9 2001/03/26 11:28:20 ghostgum Exp $ */
- /*
- * 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
- * Modified by Pierre Arnaud 1999-02-18 (see description below)
- * Modified by lpd 1999-04-03 for compatibility with Borland C++ 4.5.
- * Modified by Pierre Arnaud 1999-10-03 (accept b&w printing on color printers).
- * Modified by Pierre Arnaud 1999-11-20 (accept lower resolution)
- * Bug fixed by Pierre Arnaud 2000-03-09 (win_pr2_put_params error when is_open)
- * Bug fixed by Pierre Arnaud 2000-03-20 (win_pr2_set_bpp did not set anti_alias)
- * Bug fixed by Pierre Arnaud 2000-03-22 (win_pr2_set_bpp depth was wrong)
- * Modified by Pierre Arnaud 2000-12-12 (mainly added support for Tumble)
- * Bug fixed by Pierre Arnaud 2000-12-18 (-dQueryUser now works from cmd line)
- */
- /* This driver uses the printer default size and resolution and
- * ignores page size and resolution set using -gWIDTHxHEIGHT and
- * -rXxY. You must still set the correct PageSize to get the
- * correct clipping path.
- * The code in win_pr2_getdc() does try to set the printer page
- * size from the PostScript PageSize, but it isn't working
- * reliably at the moment.
- *
- * This driver doesn't work with some Windows printer drivers.
- * The reason is unknown. All printers to which I have access
- * work.
- *
- * rjl 1997-11-20
- */
- /* Additions by Pierre Arnaud (Pierre.Arnaud@opac.ch)
- *
- * The driver has been extended in order to provide some run-time
- * feed-back about the default Windows printer and to give the user
- * the opportunity to select the printer's properties before the
- * device gets opened (and any spooling starts).
- *
- * The driver returns an additional property named "UserSettings".
- * This is a dictionary which contens are valid only after setting
- * the QueryUser property (see below). The UserSettings dict contains
- * the following keys:
- *
- * DocumentRange [begin end] (int array, can be set)
- * Defines the range of pages in the document; [1 10] would
- * describe a document starting at page 1 and ending at page 10.
- *
- * SelectedRange [begin end] (int array, can be set)
- * Defines the pages the user wants to print.
- *
- * MediaSize [width height] (float array, read only)
- * Current printer's media size.
- *
- * Copies n (integer, can be set)
- * User selected number of copies.
- *
- * PrintCopies n (integer, read only)
- * Number of copies which must be printed by Ghostscript itself.
- * This is still experimental.
- *
- * DocumentName name (string, can be set)
- * Name to be associated with the print job.
- *
- * UserChangedSettings (bool, read only)
- * Set to 'true' if the last QueryUser operation succeeded.
- *
- * Paper n (integer, can be set)
- * Windows paper selection (0 = automatic).
- *
- * Orient n (integer, can be set)
- * Windows paper orientation (0 = automatic).
- *
- * Color n (integer, can be set)
- * Windows color (0 = automatic, 1 = monochrome, 2 = color).
- *
- * MaxResolution n (integer, can be set)
- * Maximum resolution in pixels pet inch (0 = no maximum). If
- * the printer has a higher resolution than the maximum, trim
- * the used resolution to the best one (dpi_chosen <= dpi_max,
- * with dpi_chosen = dpi_printer / ratio).
- */
- /* Supported printer parameters are :
- *
- * -dBitsPerPixel=n
- * Override what the Window printer driver returns.
- *
- * -dNoCancel
- * Don't display cancel dialog box. Useful for unattended or
- * console EXE operation.
- *
- * -dQueryUser=n
- * Query user interactively for the destination printer, before
- * the device gets opened. This fills in the UserSettings dict
- * and the OutputFile name properties. The following values are
- * supported for n:
- * 1 => show standard Print dialog
- * 2 => show Print Setup dialog instead
- * 3 => select default printer
- * other, does nothing
- *
- * The /Duplex & /Tumble keys of the setpagedevice dict are supported
- * if the Windows printer supports duplex printing.
- */
- #include "gdevprn.h"
- #include "gdevpccm.h"
- #include "windows_.h"
- #include <shellapi.h>
- #include "gp_mswin.h"
- #include "gp.h"
- #include "gpcheck.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_get_params(win_pr2_get_params);
- private dev_proc_put_params(win_pr2_put_params);
- private void win_pr2_set_bpp(gx_device * dev, int depth);
- private const 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,
- win_pr2_get_params, win_pr2_put_params);
- #define PARENT_WINDOW HWND_DESKTOP
- BOOL CALLBACK CancelDlgProc(HWND, UINT, WPARAM, LPARAM);
- BOOL CALLBACK AbortProc2(HDC, int);
- /* 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;
- bool nocancel;
- int doc_page_begin; /* first page number in document */
- int doc_page_end; /* last page number in document */
- int user_page_begin; /* user's choice: first page to print */
- int user_page_end; /* user's choice: last page to print */
- int user_copies; /* user's choice: number of copies */
- int print_copies; /* number of times GS should print each page */
- float user_media_size[2]; /* width/height of media selected by user */
- char doc_name[200]; /* name of document for the spooler */
- char paper_name[64]; /* name of selected paper format */
- bool user_changed_settings; /* true if user validated dialog */
- int user_paper; /* user's choice: paper format */
- int user_orient; /* user's choice: paper orientation */
- int user_color; /* user's choice: color format */
- int max_dpi; /* maximum resolution in DPI */
- int ratio; /* stretch ratio when printing */
- int selected_bpp; /* selected bpp, memorised by win_pr2_set_bpp */
- bool tumble; /* tumble setting (with duplex) */
- int query_user; /* query user (-dQueryUser) */
- HANDLE win32_hdevmode; /* handle to device mode information */
- HANDLE win32_hdevnames; /* handle to device names information */
- DLGPROC lpfnAbortProc;
- DLGPROC lpfnCancelProc;
- HWND hDlgModeless;
- bool use_old_spool_name; /* user prefers old \\spool\ name */
- gx_device_win_pr2* original_device; /* used to detect copies */
- };
- gx_device_win_pr2 far_data gs_mswinpr2_device =
- {
- prn_device_std_body(gx_device_win_pr2, win_pr2_procs, "mswinpr2",
- DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 72.0, 72.0,
- 0, 0, 0, 0,
- 0, win_pr2_print_page), /* depth = 0 */
- 0, /* hdcprn */
- 0, /* nocancel */
- 0, /* doc_page_begin */
- 0, /* doc_page_end */
- 0, /* user_page_begin */
- 0, /* user_page_end */
- 1, /* user_copies */
- 1, /* print_copies */
- { 0.0, 0.0 }, /* user_media_size */
- { 0 }, /* doc_name */
- { 0 }, /* paper_name */
- 0, /* user_changed_settings */
- 0, /* user_paper */
- 0, /* user_orient */
- 0, /* user_color */
- 0, /* max_dpi */
- 0, /* ratio */
- 0, /* selected_bpp */
- false, /* tumble */
- -1, /* query_user */
- NULL, /* win32_hdevmode */
- NULL, /* win32_hdevnames */
- NULL, /* lpfnAbortProc */
- NULL, /* lpfnCancelProc */
- false, /* use_old_spool_name */
- NULL /* original_device */
- };
- /********************************************************************************/
- private int win_pr2_getdc(gx_device_win_pr2 * dev);
- private int win_pr2_update_dev(gx_device_win_pr2 * dev, LPDEVMODE pdevmode);
- private int win_pr2_update_win(gx_device_win_pr2 * dev, LPDEVMODE pdevmode);
- private int win_pr2_print_setup_interaction(gx_device_win_pr2 * dev, int mode);
- private int win_pr2_write_user_settings(gx_device_win_pr2 * dev, gs_param_list * plist);
- private int win_pr2_read_user_settings(gx_device_win_pr2 * dev, gs_param_list * plist);
- private void win_pr2_copy_check(gx_device_win_pr2 * dev);
- /********************************************************************************/
- /* 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;
- DOCINFO docinfo;
- float ratio = 1.0;
-
- win_pr2_copy_check(wdev);
- /* get a HDC for the printer */
- if ((wdev->win32_hdevmode) &&
- (wdev->win32_hdevnames)) {
- /* The user has already had the opportunity to choose the output */
- /* file interactively. Just use the specified parameters. */
-
- LPDEVMODE devmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
- LPDEVNAMES devnames = (LPDEVNAMES) GlobalLock(wdev->win32_hdevnames);
-
- const char* driver = (char*)(devnames)+(devnames->wDriverOffset);
- const char* device = (char*)(devnames)+(devnames->wDeviceOffset);
- const char* output = (char*)(devnames)+(devnames->wOutputOffset);
-
- wdev->hdcprn = CreateDC(driver, device, output, devmode);
-
- GlobalUnlock(wdev->win32_hdevmode);
- GlobalUnlock(wdev->win32_hdevnames);
-
- if (wdev->hdcprn == NULL) {
- return gs_error_Fatal;
- }
-
- } else if (!win_pr2_getdc(wdev)) {
- /* couldn't get a printer from -sOutputFile= */
- /* Prompt with dialog box */
-
- LPDEVMODE devmode = NULL;
- memset(&pd, 0, sizeof(pd));
-
- pd.lStructSize = sizeof(pd);
- pd.hwndOwner = PARENT_WINDOW;
- pd.Flags = PD_RETURNDC;
- pd.nMinPage = wdev->doc_page_begin;
- pd.nMaxPage = wdev->doc_page_end;
- pd.nFromPage = wdev->user_page_begin;
- pd.nToPage = wdev->user_page_end;
- pd.nCopies = wdev->user_copies;
-
- if (!PrintDlg(&pd)) {
- /* device not opened - exit ghostscript */
- return gs_error_Fatal; /* exit Ghostscript cleanly */
- }
-
- devmode = GlobalLock(pd.hDevMode);
- win_pr2_update_dev(wdev,devmode);
- GlobalUnlock(pd.hDevMode);
-
- if (wdev->win32_hdevmode)
- GlobalFree(wdev->win32_hdevmode);
- if (wdev->win32_hdevnames)
- GlobalFree(wdev->win32_hdevnames);
-
- wdev->hdcprn = pd.hDC;
- wdev->win32_hdevmode = pd.hDevMode;
- wdev->win32_hdevnames = pd.hDevNames;
-
- pd.hDevMode = NULL;
- pd.hDevNames = NULL;
- }
- if (!(GetDeviceCaps(wdev->hdcprn, RASTERCAPS) != RC_DIBTODEV)) {
- errprintf( "Windows printer does not have RC_DIBTODEV\n");
- DeleteDC(wdev->hdcprn);
- return gs_error_limitcheck;
- }
- /* initialise printer, install abort proc */
- wdev->lpfnAbortProc = (DLGPROC) AbortProc2;
- SetAbortProc(wdev->hdcprn, (ABORTPROC) wdev->lpfnAbortProc);
- /*
- * Some versions of the Windows headers include lpszDatatype and fwType,
- * and some don't. Since we want to set these fields to zero anyway,
- * we just start by zeroing the whole structure.
- */
- memset(&docinfo, 0, sizeof(docinfo));
- docinfo.cbSize = sizeof(docinfo);
- docinfo.lpszDocName = wdev->doc_name;
- /*docinfo.lpszOutput = NULL;*/
- /*docinfo.lpszDatatype = NULL;*/
- /*docinfo.fwType = 0;*/
- if (docinfo.lpszDocName[0] == 0) {
- docinfo.lpszDocName = "Ghostscript output";
- }
- if (StartDoc(wdev->hdcprn, &docinfo) <= 0) {
- errprintf("Printer StartDoc failed (error %08x)\n", GetLastError());
- DeleteDC(wdev->hdcprn);
- return gs_error_limitcheck;
- }
-
- dev->x_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSX);
- dev->y_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSY);
-
- wdev->ratio = 1;
-
- if (wdev->max_dpi > 50) {
-
- float dpi_x = dev->x_pixels_per_inch;
- float dpi_y = dev->y_pixels_per_inch;
-
- while ((dev->x_pixels_per_inch > wdev->max_dpi)
- || (dev->y_pixels_per_inch > wdev->max_dpi)) {
- ratio += 1.0;
- wdev->ratio ++;
- dev->x_pixels_per_inch = dpi_x / ratio;
- dev->y_pixels_per_inch = dpi_y / ratio;
- }
- }
-
- size.x = GetDeviceCaps(wdev->hdcprn, PHYSICALWIDTH);
- size.y = GetDeviceCaps(wdev->hdcprn, PHYSICALHEIGHT);
- gx_device_set_width_height(dev, (int)(size.x / ratio), (int)(size.y / ratio));
- offset.x = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETX);
- offset.y = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETY);
-
- /* m[] gives margins in inches */
- m[0] /*left */ = offset.x / dev->x_pixels_per_inch / ratio;
- m[3] /*top */ = offset.y / dev->y_pixels_per_inch / ratio;
- m[2] /*right */ = (size.x - offset.x - GetDeviceCaps(wdev->hdcprn, HORZRES)) / dev->x_pixels_per_inch / ratio;
- m[1] /*bottom */ = (size.y - offset.y - GetDeviceCaps(wdev->hdcprn, VERTRES)) / dev->y_pixels_per_inch / ratio;
- 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, 4 (but use only 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);
- /* delete unwanted temporary file */
- unlink(wdev->fname);
- if (!wdev->nocancel) {
- /* inform user of progress with dialog box and allow cancel */
- wdev->lpfnCancelProc = (DLGPROC) CancelDlgProc;
- wdev->hDlgModeless = CreateDialog(phInstance, "CancelDlgBox",
- PARENT_WINDOW, wdev->lpfnCancelProc);
- ShowWindow(wdev->hDlgModeless, SW_HIDE);
- }
- return code;
- };
- /* Close the win_pr2 driver */
- private int
- win_pr2_close(gx_device * dev)
- {
- int code;
- int aborted = FALSE;
- win_pr2_copy_check(wdev);
- /* Free resources */
- if (!wdev->nocancel) {
- if (!wdev->hDlgModeless)
- aborted = TRUE;
- else
- DestroyWindow(wdev->hDlgModeless);
- wdev->hDlgModeless = 0;
- }
- if (aborted)
- AbortDoc(wdev->hdcprn);
- else
- EndDoc(wdev->hdcprn);
- DeleteDC(wdev->hdcprn);
- if (wdev->win32_hdevmode != NULL) {
- GlobalFree(wdev->win32_hdevmode);
- wdev->win32_hdevmode = NULL;
- }
- if (wdev->win32_hdevnames != NULL) {
- GlobalFree(wdev->win32_hdevnames);
- wdev->win32_hdevnames = NULL;
- }
- code = gdev_prn_close(dev);
- 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);
- ulong bmp_raster_multi;
- int scan_lines, yslice, lines, i;
- int width;
- int depth = pdev->color_info.depth;
- byte *row;
- int y;
- int code = 0; /* return code */
- MSG msg;
- char dlgtext[32];
- HGLOBAL hrow;
- int ratio = ((gx_device_win_pr2 *)pdev)->ratio;
- struct bmi_s {
- BITMAPINFOHEADER h;
- RGBQUAD pal[256];
- } bmi;
- scan_lines = dev_print_scan_lines(pdev);
- width = (int)(pdev->width - ((dev_l_margin(pdev) + dev_r_margin(pdev) -
- dev_x_offset(pdev)) * pdev->x_pixels_per_inch));
- yslice = 65535 / bmp_raster; /* max lines in 64k */
- bmp_raster_multi = bmp_raster * yslice;
- hrow = GlobalAlloc(0, bmp_raster_multi);
- row = GlobalLock(hrow);
- 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 = yslice;
- 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 */
- StartPage(wdev->hdcprn);
-
- /* 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;
- }
- if (!wdev->nocancel) {
- sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount) + 1);
- SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PRINTING), dlgtext);
- ShowWindow(wdev->hDlgModeless, SW_SHOW);
- }
- for (y = 0; y < scan_lines;) {
- /* copy slice to row buffer */
- if (y > scan_lines - yslice)
- lines = scan_lines - y;
- else
- lines = yslice;
- for (i = 0; i < lines; i++)
- gdev_prn_copy_scan_lines(pdev, y + i,
- row + (bmp_raster * (lines - 1 - i)), raster);
-
- if (ratio > 1) {
- StretchDIBits(wdev->hdcprn, 0, y*ratio, pdev->width*ratio, lines*ratio,
- 0, 0, pdev->width, lines,
- row,
- (BITMAPINFO FAR *) & bmi, DIB_RGB_COLORS, SRCCOPY);
- } else {
- SetDIBitsToDevice(wdev->hdcprn, 0, y, pdev->width, lines,
- 0, 0, 0, lines,
- row,
- (BITMAPINFO FAR *) & bmi, DIB_RGB_COLORS);
- }
- y += lines;
- if (!wdev->nocancel) {
- /* inform user of progress */
- sprintf(dlgtext, "%d%% done", (int)(y * 100L / scan_lines));
- SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE), dlgtext);
- }
- /* process message loop */
- while (PeekMessage(&msg, wdev->hDlgModeless, 0, 0, PM_REMOVE)) {
- if ((wdev->hDlgModeless == 0) || !IsDialogMessage(wdev->hDlgModeless, &msg)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- if ((!wdev->nocancel) && (wdev->hDlgModeless == 0)) {
- /* user pressed cancel button */
- break;
- }
- }
- if ((!wdev->nocancel) && (wdev->hDlgModeless == 0))
- code = gs_error_Fatal; /* exit Ghostscript cleanly */
- else {
- /* push out the page */
- if (!wdev->nocancel)
- SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE),
- "Ejecting page...");
- EndPage(wdev->hdcprn);
- if (!wdev->nocancel)
- ShowWindow(wdev->hDlgModeless, SW_HIDE);
- }
- bmp_done:
- GlobalUnlock(hrow);
- GlobalFree(hrow);
- 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;
- depth = 24;
- } 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;
- depth = 8;
- } 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 = dci_values(3, 4, 1, 1, 2, 2);
- dev->color_info = win_pr2_4color;
- depth = 4;
- } 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;
- depth = 1;
- }
-
- ((gx_device_win_pr2 *)dev)->selected_bpp = depth;
- }
- /********************************************************************************/
- /* Get device parameters */
- int
- win_pr2_get_params(gx_device * pdev, gs_param_list * plist)
- {
- int code = gdev_prn_get_params(pdev, plist);
- win_pr2_copy_check(wdev);
- if (code >= 0)
- code = param_write_bool(plist, "NoCancel",
- &(wdev->nocancel));
- if (code >= 0)
- code = param_write_bool(plist, "QueryUser",
- &(wdev->query_user));
- if (code >= 0)
- code = win_pr2_write_user_settings(wdev, plist);
-
- if ((code >= 0) && (wdev->Duplex_set > 0))
- code = param_write_bool(plist, "Tumble",
- &(wdev->tumble));
- return code;
- }
- /* We implement this ourselves so that we can change BitsPerPixel */
- /* before the device is opened */
- int
- win_pr2_put_params(gx_device * pdev, gs_param_list * plist)
- {
- int ecode = 0, code;
- int old_bpp = pdev->color_info.depth;
- int bpp = old_bpp;
- bool tumble = wdev->tumble;
- bool nocancel = wdev->nocancel;
- int queryuser = 0;
- bool old_duplex = wdev->Duplex;
- bool old_tumble = wdev->tumble;
- int old_orient = wdev->user_orient;
- int old_color = wdev->user_color;
- int old_paper = wdev->user_paper;
- int old_mx_dpi = wdev->max_dpi;
- if (wdev->Duplex_set < 0) {
- wdev->Duplex_set = 0;
- wdev->Duplex = false;
- wdev->tumble = false;
- }
-
- win_pr2_copy_check(wdev);
- code = win_pr2_read_user_settings(wdev, plist);
- switch (code = param_read_int(plist, "BitsPerPixel", &bpp)) {
- case 0:
- if (pdev->is_open) {
- if (wdev->selected_bpp == bpp) {
- break;
- }
- ecode = gs_error_rangecheck;
- } else { /* change dev->color_info is valid before device is opened */
- win_pr2_set_bpp(pdev, bpp);
- break;
- }
- goto bppe;
- default:
- ecode = code;
- bppe:param_signal_error(plist, "BitsPerPixel", ecode);
- case 1:
- break;
- }
- switch (code = param_read_bool(plist, "NoCancel", &nocancel)) {
- case 0:
- if (pdev->is_open) {
- if (wdev->nocancel == nocancel) {
- break;
- }
- ecode = gs_error_rangecheck;
- } else {
- wdev->nocancel = nocancel;
- break;
- }
- goto nocancele;
- default:
- ecode = code;
- nocancele:param_signal_error(plist, "NoCancel", ecode);
- case 1:
- break;
- }
- switch (code = param_read_bool(plist, "Tumble", &tumble)) {
- case 0:
- wdev->tumble = tumble;
- break;
- default:
- ecode = code;
- param_signal_error(plist, "Tumble", ecode);
- case 1:
- break;
- }
- switch (code = param_read_int(plist, "QueryUser", &queryuser)) {
- case 0:
- if ((queryuser > 0) &&
- (queryuser < 4)) {
- win_pr2_print_setup_interaction(wdev, queryuser);
- }
- break;
- default:
- ecode = code;
- param_signal_error(plist, "QueryUser", ecode);
- case 1:
- break;
- }
- if (ecode >= 0)
- ecode = gdev_prn_put_params(pdev, plist);
-
- if (wdev->win32_hdevmode && wdev->hdcprn) {
- if ( (old_duplex != wdev->Duplex)
- || (old_tumble != wdev->tumble)
- || (old_orient != wdev->user_orient)
- || (old_color != wdev->user_color)
- || (old_paper != wdev->user_paper)
- || (old_mx_dpi != wdev->max_dpi) ) {
-
- LPDEVMODE pdevmode = GlobalLock(wdev->win32_hdevmode);
-
- if (pdevmode) {
- win_pr2_update_win(wdev, pdevmode);
- ResetDC(wdev->hdcprn, pdevmode);
- GlobalUnlock(pdevmode);
- }
- }
- }
-
- return ecode;
- }
- #undef wdev
- /********************************************************************************/
- /* Get Device Context for printer */
- private int
- win_pr2_getdc(gx_device_win_pr2 * wdev)
- {
- char *device;
- char *devices;
- char *p;
- char driverbuf[512];
- char *driver;
- char *output;
- char *devcap;
- int devcapsize;
- int size;
- int i, n;
- POINT *pp;
- int paperindex;
- int paperwidth, paperheight;
- int orientation;
- int papersize;
- char papername[64];
- char drvname[32];
- HINSTANCE hlib;
- LPFNDEVMODE pfnExtDeviceMode;
- LPFNDEVCAPS pfnDeviceCapabilities;
- LPDEVMODE podevmode, pidevmode;
- HANDLE hprinter;
- /* first try to derive the printer name from -sOutputFile= */
- /* is printer if name prefixed by \\spool\ or by %printer% */
- if (is_spool(wdev->fname)) {
- device = wdev->fname + 8; /* skip over \\spool\ */
- wdev->use_old_spool_name = true;
- } else if (strncmp("%printer%",wdev->fname,9) == 0) {
- device = wdev->fname + 9; /* skip over %printer% */
- wdev->use_old_spool_name = false;
- } else {
- return FALSE;
- }
- /* now try to match the printer name against the [Devices] section */
- if ((devices = gs_malloc(4096, 1, "win_pr2_getdc")) == (char *)NULL)
- return FALSE;
- GetProfileString("Devices", NULL, "", devices, 4096);
- p = devices;
- while (*p) {
- if (stricmp(p, device) == 0)
- break;
- p += strlen(p) + 1;
- }
- if (*p == '\0')
- p = NULL;
- gs_free(devices, 4096, 1, "win_pr2_getdc");
- if (p == NULL)
- return FALSE; /* doesn't match an available printer */
- /* the printer exists, get the remaining information from win.ini */
- GetProfileString("Devices", device, "", driverbuf, sizeof(driverbuf));
- driver = strtok(driverbuf, ",");
- output = strtok(NULL, ",");
- if (is_win32s)
- {
- strcpy(drvname, driver);
- strcat(drvname, ".drv");
- driver = drvname;
- }
- if (!is_win32s) { /* Win32 */
- if (!OpenPrinter(device, &hprinter, NULL))
- return FALSE;
- size = DocumentProperties(NULL, hprinter, device, NULL, NULL, 0);
- if ((podevmode = gs_malloc(size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) {
- ClosePrinter(hprinter);
- return FALSE;
- }
- if ((pidevmode = gs_malloc(size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) {
- gs_free(podevmode, size, 1, "win_pr2_getdc");
- ClosePrinter(hprinter);
- return FALSE;
- }
- DocumentProperties(NULL, hprinter, device, podevmode, NULL, DM_OUT_BUFFER);
- pfnDeviceCapabilities = (LPFNDEVCAPS) DeviceCapabilities;
- } else
- { /* Win16 and Win32s */
- /* now load the printer driver */
- hlib = LoadLibrary(driver);
- if (hlib < (HINSTANCE) HINSTANCE_ERROR)
- return FALSE;
- /* call ExtDeviceMode() to get default parameters */
- pfnExtDeviceMode = (LPFNDEVMODE) GetProcAddress(hlib, "ExtDeviceMode");
- if (pfnExtDeviceMode == (LPFNDEVMODE) NULL) {
- FreeLibrary(hlib);
- return FALSE;
- }
- pfnDeviceCapabilities = (LPFNDEVCAPS) GetProcAddress(hlib, "DeviceCapabilities");
- if (pfnDeviceCapabilities == (LPFNDEVCAPS) NULL) {
- FreeLibrary(hlib);
- return FALSE;
- }
- size = pfnExtDeviceMode(NULL, hlib, NULL, device, output, NULL, NULL, 0);
- if ((podevmode = gs_malloc(size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) {
- FreeLibrary(hlib);
- return FALSE;
- }
- if ((pidevmode = gs_malloc(size, 1, "win_pr2_getdc")) == (LPDEVMODE) NULL) {
- gs_free(podevmode, size, 1, "win_pr2_getdc");
- FreeLibrary(hlib);
- return FALSE;
- }
- pfnExtDeviceMode(NULL, hlib, podevmode, device, output,
- NULL, NULL, DM_OUT_BUFFER);
- }
- /* now find out what paper sizes are available */
- devcapsize = pfnDeviceCapabilities(device, output, DC_PAPERSIZE, NULL, NULL);
- devcapsize *= sizeof(POINT);
- if ((devcap = gs_malloc(devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
- return FALSE;
- n = pfnDeviceCapabilities(device, output, DC_PAPERSIZE, devcap, NULL);
- paperwidth = (int)(wdev->MediaSize[0] * 254 / 72);
- paperheight = (int)(wdev->MediaSize[1] * 254 / 72);
- papername[0] = '\0';
- papersize = 0;
- paperindex = -1;
- orientation = 0;
- pp = (POINT *) devcap;
- for (i = 0; i < n; i++, pp++) {
- if ((pp->x < paperwidth + 20) && (pp->x > paperwidth - 20) &&
- (pp->y < paperheight + 20) && (pp->y > paperheight - 20)) {
- paperindex = i;
- paperwidth = pp->x;
- paperheight = pp->y;
- orientation = DMORIENT_PORTRAIT;
- break;
- }
- }
- if (paperindex < 0) {
- /* try again in landscape */
- pp = (POINT *) devcap;
- for (i = 0; i < n; i++, pp++) {
- if ((pp->x < paperheight + 20) && (pp->x > paperheight - 20) &&
- (pp->y < paperwidth + 20) && (pp->y > paperwidth - 20)) {
- paperindex = i;
- paperwidth = pp->x;
- paperheight = pp->y;
- orientation = DMORIENT_LANDSCAPE;
- break;
- }
- }
- }
- gs_free(devcap, devcapsize, 1, "win_pr2_getdc");
-
- /* get the dmPaperSize */
- devcapsize = pfnDeviceCapabilities(device, output, DC_PAPERS, NULL, NULL);
- devcapsize *= sizeof(WORD);
- if ((devcap = gs_malloc(devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
- return FALSE;
- n = pfnDeviceCapabilities(device, output, DC_PAPERS, devcap, NULL);
- if ((paperindex >= 0) && (paperindex < n))
- papersize = ((WORD *) devcap)[paperindex];
- gs_free(devcap, devcapsize, 1, "win_pr2_getdc");
- /* get the paper name */
- devcapsize = pfnDeviceCapabilities(device, output, DC_PAPERNAMES, NULL, NULL);
- devcapsize *= 64;
- if ((devcap = gs_malloc(devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
- return FALSE;
- n = pfnDeviceCapabilities(device, output, DC_PAPERNAMES, devcap, NULL);
- if ((paperindex >= 0) && (paperindex < n))
- strcpy(papername, devcap + paperindex * 64);
- gs_free(devcap, devcapsize, 1, "win_pr2_getdc");
- memcpy(pidevmode, podevmode, size);
- pidevmode->dmFields = 0;
-
- wdev->paper_name[0] = 0;
- if ( (wdev->user_paper)
- && (wdev->user_paper != papersize) ) {
- papersize = wdev->user_paper;
- paperheight = 0;
- paperwidth = 0;
- papername[0] = 0;
- }
- if (wdev->user_orient) {
- orientation = wdev->user_orient;
- }
-
- pidevmode->dmFields &= ~(DM_PAPERSIZE | DM_ORIENTATION | DM_COLOR | DM_PAPERLENGTH | DM_PAPERWIDTH | DM_DUPLEX);
- pidevmode->dmFields |= DM_DEFAULTSOURCE;
- pidevmode->dmDefaultSource = 0;
-
- if (orientation) {
- wdev->user_orient = orientation;
- }
- if (papersize) {
- wdev->user_paper = papersize;
- strcpy (wdev->paper_name, papername);
- }
-
- if (paperheight && paperwidth) {
- pidevmode->dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH);
- pidevmode->dmPaperWidth = paperwidth;
- pidevmode->dmPaperLength = paperheight;
- wdev->user_media_size[0] = paperwidth / 254.0 * 72.0;
- wdev->user_media_size[1] = paperheight / 254.0 * 72.0;
- }
-
- if (DeviceCapabilities(device, output, DC_DUPLEX, NULL, NULL)) {
- wdev->Duplex_set = 1;
- }
-
- win_pr2_update_win(wdev, pidevmode);
-
- if (!is_win32s) {
-
- /* merge the entries */
- DocumentProperties(NULL, hprinter, device, podevmode, pidevmode, DM_IN_BUFFER | DM_OUT_BUFFER);
- ClosePrinter(hprinter);
-
- /* now get a DC */
- wdev->hdcprn = CreateDC(driver, device, NULL, podevmode);
- } else
- { /* Win16 and Win32s */
- pfnExtDeviceMode(NULL, hlib, podevmode, device, output,
- pidevmode, NULL, DM_IN_BUFFER | DM_OUT_BUFFER);
- /* release the printer driver */
- FreeLibrary(hlib);
- /* now get a DC */
- if (is_win32s)
- strtok(driver, "."); /* remove .drv */
- wdev->hdcprn = CreateDC(driver, device, output, podevmode);
- }
-
- if (wdev->win32_hdevmode == NULL) {
- wdev->win32_hdevmode = GlobalAlloc(0, sizeof(DEVMODE));
- }
-
- if (wdev->win32_hdevmode) {
- LPDEVMODE pdevmode = (LPDEVMODE) GlobalLock(GlobalLock(wdev->win32_hdevmode));
- if (pdevmode) {
- memcpy(pdevmode, podevmode, sizeof(DEVMODE));
- GlobalUnlock(wdev->win32_hdevmode);
- }
- }
- gs_free(pidevmode, size, 1, "win_pr2_getdc");
- gs_free(podevmode, size, 1, "win_pr2_getdc");
- if (wdev->hdcprn != (HDC) NULL)
- return TRUE; /* success */
- /* fall back to prompting user */
- return FALSE;
- }
- /*
- * Minimalist update of the wdev parameters (mainly for the
- * UserSettings parameters).
- */
- private int
- win_pr2_update_dev(gx_device_win_pr2 * dev, LPDEVMODE pdevmode)
- {
- if (pdevmode == 0)
- return FALSE;
-
- if (pdevmode->dmFields & DM_COLOR) {
- dev->user_color = pdevmode->dmColor;
- }
- if (pdevmode->dmFields & DM_ORIENTATION) {
- dev->user_orient = pdevmode->dmOrientation;
- }
- if (pdevmode->dmFields & DM_PAPERSIZE) {
- dev->user_paper = pdevmode->dmPaperSize;
- dev->user_media_size[0] = pdevmode->dmPaperWidth / 254.0 * 72.0;
- dev->user_media_size[1] = pdevmode->dmPaperLength / 254.0 * 72.0;
- dev->paper_name[0] = 0; /* unknown paper size */
- }
- if (pdevmode->dmFields & DM_DUPLEX) {
- dev->Duplex_set = 1;
- dev->Duplex = pdevmode->dmDuplex == DMDUP_SIMPLEX ? false : true;
- dev->tumble = pdevmode->dmDuplex == DMDUP_HORIZONTAL ? true : false;
- }
-
- return TRUE;
- }
- private int
- win_pr2_update_win(gx_device_win_pr2 * dev, LPDEVMODE pdevmode)
- {
- if (dev->Duplex_set > 0) {
- pdevmode->dmFields |= DM_DUPLEX;
- pdevmode->dmDuplex = DMDUP_SIMPLEX;
- if (dev->Duplex) {
- if (dev->tumble == false) {
- pdevmode->dmDuplex = DMDUP_VERTICAL;
- } else {
- pdevmode->dmDuplex = DMDUP_HORIZONTAL;
- }
- }
- }
-
- if (dev->user_color) {
- pdevmode->dmColor = dev->user_color;
- pdevmode->dmFields |= DM_COLOR;
- }
-
- if (dev->user_orient) {
- pdevmode->dmFields |= DM_ORIENTATION;
- pdevmode->dmOrientation = dev->user_orient;
- }
-
- if (dev->user_paper) {
- pdevmode->dmFields |= DM_PAPERSIZE;
- pdevmode->dmPaperSize = dev->user_paper;
- }
- return 0;
- }
- /********************************************************************************/
- #define BEGIN_ARRAY_PARAM(pread, pname, pa, psize, e)\
- switch ( code = pread(dict.list, (param_name = pname), &(pa)) )\
- {\
- case 0:\
- if ( (pa).size != psize )\
- ecode = gs_note_error(gs_error_rangecheck);\
- else {
- /* The body of the processing code goes here. */
- /* If it succeeds, it should do a 'break'; */
- /* if it fails, it should set ecode and fall through. */
- #define END_ARRAY_PARAM(pa, e)\
- }\
- goto e;\
- default:\
- ecode = code;\
- e: param_signal_error(dict.list, param_name, ecode);\
- case 1:\
- (pa).data = 0; /* mark as not filled */\
- }
- /* Put the user params from UserSettings into our */
- /* internal variables. */
- private int
- win_pr2_read_user_settings(gx_device_win_pr2 * wdev, gs_param_list * plist)
- {
- gs_param_dict dict;
- gs_param_string docn = { 0 };
- const char* dict_name = "UserSettings";
- const char* param_name = "";
- int code = 0;
- int ecode = 0;
- switch (code = param_begin_read_dict(plist, dict_name, &dict, false)) {
- default:
- param_signal_error(plist, dict_name, code);
- return code;
- case 1:
- break;
- case 0:
- {
- gs_param_int_array ia;
-
- BEGIN_ARRAY_PARAM(param_read_int_array, "DocumentRange", ia, 2, ia)
- if ((ia.data[0] < 0) ||
- (ia.data[1] < 0) ||
- (ia.data[0] > ia.data[1]))
- ecode = gs_note_error(gs_error_rangecheck);
- wdev->doc_page_begin = ia.data[0];
- wdev->doc_page_end = ia.data[1];
- END_ARRAY_PARAM(ia, doc_range_error)
-
- BEGIN_ARRAY_PARAM(param_read_int_array, "SelectedRange", ia, 2, ia)
- if ((ia.data[0] < 0) ||
- (ia.data[1] < 0) ||
- (ia.data[0] > ia.data[1]))
- ecode = gs_note_error(gs_error_rangecheck);
- wdev->user_page_begin = ia.data[0];
- wdev->user_page_end = ia.data[1];
- END_ARRAY_PARAM(ia, sel_range_error)
-
- param_read_int(dict.list, "Copies", &wdev->user_copies);
- param_read_int(dict.list, "Paper", &wdev->user_paper);
- param_read_int(dict.list, "Orientation", &wdev->user_orient);
- param_read_int(dict.list, "Color", &wdev->user_color);
- param_read_int(dict.list, "MaxResolution", &wdev->max_dpi);
-
- switch (code = param_read_string(dict.list, (param_name = "DocumentName"), &docn)) {
- case 0:
- if (docn.size < sizeof(wdev->doc_name))
- break;
- code = gs_error_rangecheck;
- /* fall through */
- default:
- ecode = code;
- param_signal_error(plist, param_name, ecode);
- /* fall through */
- case 1:
- docn.data = 0;
- break;
- }
-
- param_end_read_dict(plist, dict_name, &dict);
-
- if (docn.data) {
- memcpy(wdev->doc_name, docn.data, docn.size);
- wdev->doc_name[docn.size] = 0;
- }
-
- wdev->print_copies = 1;
-
- if (wdev->win32_hdevmode) {
- LPDEVMODE devmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
- if (devmode) {
- devmode->dmCopies = wdev->user_copies;
- devmode->dmPaperSize = wdev->user_paper;
- devmode->dmOrientation = wdev->user_orient;
- devmode->dmColor = wdev->user_color;
- GlobalUnlock(wdev->win32_hdevmode);
- }
- }
- }
- break;
- }
- return code;
- }
- private int
- win_pr2_write_user_settings(gx_device_win_pr2 * wdev, gs_param_list * plist)
- {
- gs_param_dict dict;
- gs_param_int_array range;
- gs_param_float_array box;
- gs_param_string docn;
- gs_param_string papn;
- int array[2];
- const char* pname = "UserSettings";
- int code;
- dict.size = 12;
- code = param_begin_write_dict(plist, pname, &dict, false);
- if (code < 0) return code;
- array[0] = wdev->doc_page_begin;
- array[1] = wdev->doc_page_end;
- range.data = array;
- range.size = 2;
- range.persistent = false;
- code = param_write_int_array(dict.list, "DocumentRange", &range);
- if (code < 0) goto error;
- array[0] = wdev->user_page_begin;
- array[1] = wdev->user_page_end;
- range.data = array;
- range.size = 2;
- range.persistent = false;
- code = param_write_int_array(dict.list, "SelectedRange", &range);
- if (code < 0) goto error;
- box.data = wdev->user_media_size;
- box.size = 2;
- box.persistent = false;
- code = param_write_float_array(dict.list, "MediaSize", &box);
- if (code < 0) goto error;
- code = param_write_int(dict.list, "Copies", &wdev->user_copies);
- if (code < 0) goto error;
- code = param_write_int(dict.list, "Paper", &wdev->user_paper);
- if (code < 0) goto error;
-
- code = param_write_int(dict.list, "Orientation", &wdev->user_orient);
- if (code < 0) goto error;
-
- code = param_write_int(dict.list, "Color", &wdev->user_color);
- if (code < 0) goto error;
-
- code = param_write_int(dict.list, "MaxResolution", &wdev->max_dpi);
- if (code < 0) goto error;
-
- code = param_write_int(dict.list, "PrintCopies", &wdev->print_copies);
- if (code < 0) goto error;
- docn.data = (const byte*)wdev->doc_name;
- docn.size = strlen(wdev->doc_name);
- docn.persistent = false;
- code = param_write_string(dict.list, "DocumentName", &docn);
- if (code < 0) goto error;
-
- papn.data = (const byte*)wdev->paper_name;
- papn.size = strlen(wdev->paper_name);
- papn.persistent = false;
-
- code = param_write_string(dict.list, "PaperName", &papn);
- if (code < 0) goto error;
- code = param_write_bool(dict.list, "UserChangedSettings", &wdev->user_changed_settings);
- error:
- param_end_write_dict(plist, pname, &dict);
- return code;
- }
- /********************************************************************************/
- /* Show up a dialog for the user to choose a printer and a paper size.
- * If mode == 3, then automatically select the default Windows printer
- * instead of asking the user.
- */
- private int
- win_pr2_print_setup_interaction(gx_device_win_pr2 * wdev, int mode)
- {
- PRINTDLG pd;
- LPDEVMODE devmode;
- LPDEVNAMES devnames;
- wdev->user_changed_settings = FALSE;
- wdev->query_user = mode;
- memset(&pd, 0, sizeof(pd));
- pd.lStructSize = sizeof(pd);
- pd.hwndOwner = PARENT_WINDOW;
- switch (mode) {
- case 2: pd.Flags = PD_PRINTSETUP; break;
- case 3: pd.Flags = PD_RETURNDEFAULT; break;
- default: pd.Flags = 0; break;
- }
- pd.Flags |= PD_USEDEVMODECOPIES;
- pd.nMinPage = wdev->doc_page_begin;
- pd.nMaxPage = wdev->doc_page_end;
- pd.nFromPage = wdev->user_page_begin;
- pd.nToPage = wdev->user_page_end;
- pd.nCopies = wdev->user_copies;
- /* Show the Print Setup dialog and let the user choose a printer
- * and a paper size/orientation.
- */
- if (!PrintDlg(&pd)) return FALSE;
- devmode = (LPDEVMODE) GlobalLock(pd.hDevMode);
- devnames = (LPDEVNAMES) GlobalLock(pd.hDevNames);
- wdev->user_changed_settings = TRUE;
- if (wdev->use_old_spool_name) {
- sprintf(wdev->fname, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset));
- } else {
- sprintf(wdev->fname, "%%printer%%%s", (char*)(devnames)+(devnames->wDeviceOffset));
- }
- if (mode == 3) {
- devmode->dmCopies = wdev->user_copies * wdev->print_copies;
- pd.nCopies = 1;
- }
- wdev->user_page_begin = pd.nFromPage;
- wdev->user_page_end = pd.nToPage;
- wdev->user_copies = devmode->dmCopies;
- wdev->print_copies = pd.nCopies;
- wdev->user_media_size[0] = devmode->dmPaperWidth / 254.0 * 72.0;
- wdev->user_media_size[1] = devmode->dmPaperLength / 254.0 * 72.0;
- wdev->user_paper = devmode->dmPaperSize;
- wdev->user_orient = devmode->dmOrientation;
- wdev->user_color = devmode->dmColor;
-
- if (devmode->dmFields & DM_DUPLEX) {
- wdev->Duplex_set = 1;
- wdev->Duplex = devmode->dmDuplex == DMDUP_SIMPLEX ? false : true;
- wdev->tumble = devmode->dmDuplex == DMDUP_HORIZONTAL ? true : false;
- }
- {
- float xppinch = 0;
- float yppinch = 0;
- const char* driver = (char*)(devnames)+(devnames->wDriverOffset);
- const char* device = (char*)(devnames)+(devnames->wDeviceOffset);
- const char* output = (char*)(devnames)+(devnames->wOutputOffset);
-
- HDC hic = CreateIC(driver, device, output, devmode);
-
- if (hic) {
- xppinch = (float)GetDeviceCaps(hic, LOGPIXELSX);
- yppinch = (float)GetDeviceCaps(hic, LOGPIXELSY);
- wdev->user_media_size[0] = GetDeviceCaps(hic, PHYSICALWIDTH) * 72.0 / xppinch;
- wdev->user_media_size[1] = GetDeviceCaps(hic, PHYSICALHEIGHT) * 72.0 / yppinch;
- DeleteDC(hic);
- }
- }
- devmode = NULL;
- devnames = NULL;
- GlobalUnlock(pd.hDevMode);
- GlobalUnlock(pd.hDevNames);
- if (wdev->win32_hdevmode != NULL) {
- GlobalFree(wdev->win32_hdevmode);
- }
- if (wdev->win32_hdevnames != NULL) {
- GlobalFree(wdev->win32_hdevnames);
- }
- wdev->win32_hdevmode = pd.hDevMode;
- wdev->win32_hdevnames = pd.hDevNames;
- return TRUE;
- }
- /* Check that we are dealing with an original device. If this
- * happens to be a copy made by "copydevice", we will have to
- * copy the original's handles to the associated Win32 params.
- */
- private void
- win_pr2_copy_check(gx_device_win_pr2 * wdev)
- {
- HGLOBAL hdevmode = wdev->win32_hdevmode;
- HGLOBAL hdevnames = wdev->win32_hdevnames;
- DWORD devmode_len = (hdevmode) ? GlobalSize(hdevmode) : 0;
- DWORD devnames_len = (hdevnames) ? GlobalSize(hdevnames) : 0;
- if (wdev->original_device == wdev)
- return;
- wdev->hdcprn = NULL;
- wdev->win32_hdevmode = NULL;
- wdev->win32_hdevnames = NULL;
- wdev->original_device = wdev;
- if (devmode_len) {
- wdev->win32_hdevmode = GlobalAlloc(0, devmode_len);
- if (wdev->win32_hdevmode) {
- memcpy(GlobalLock(wdev->win32_hdevmode), GlobalLock(hdevmode), devmode_len);
- GlobalUnlock(wdev->win32_hdevmode);
- GlobalUnlock(hdevmode);
- }
- }
- if (devnames_len) {
- wdev->win32_hdevnames = GlobalAlloc(0, devnames_len);
- if (wdev->win32_hdevnames) {
- memcpy(GlobalLock(wdev->win32_hdevnames), GlobalLock(hdevnames), devnames_len);
- GlobalUnlock(wdev->win32_hdevnames);
- GlobalUnlock(hdevnames);
- }
- }
- }
- /* Modeless dialog box - Cancel printing */
- BOOL CALLBACK
- CancelDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message) {
- case WM_INITDIALOG:
- SetWindowText(hDlg, szAppName);
- return TRUE;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDCANCEL:
- DestroyWindow(hDlg);
- EndDialog(hDlg, 0);
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL CALLBACK
- AbortProc2(HDC hdcPrn, int code)
- {
- process_interrupts();
- if (code == SP_OUTOFDISK)
- return (FALSE); /* cancel job */
- return (TRUE);
- }
|