|
|
1.1 root 1: //--------------------------------------------------------------------------
2: //
3: // Module Name: DEVMODE.C
4: //
5: // Brief Description: This module contains the PSCRIPT driver's User
6: // Default DEVMODE setting routine
7: //
8: // Author: Kent Settle (kentse)
9: // Created: 12-Dec-1992
10: //
11: // Copyright (c) 1992 Microsoft Corporation
12: //--------------------------------------------------------------------------
13:
14: #include <stddef.h>
15: #include <stdlib.h>
16: #include <string.h>
17: #include "pscript.h"
18: #include "enable.h"
19:
20: static COLORADJUSTMENT defcoloradj =
21: {
22: sizeof(COLORADJUSTMENT),
23: 0,
24: ILLUMINANT_DEVICE_DEFAULT,
25: 20000,
26: 20000,
27: 20000,
28: REFERENCE_BLACK_MIN,
29: REFERENCE_WHITE_MAX,
30: 0,
31: 0,
32: 0,
33: 0
34: };
35:
36: VOID SetFormSize(HANDLE, PSDEVMODE *, PWSTR);
37: VOID SetFormName(HANDLE, PSDEVMODE *, int);
38:
39: //--------------------------------------------------------------------------
40: // BOOL SetDefaultPSDEVMODE(pdevmode, pDeviceName, pntpd)
41: // PSDEVMODE *pdevmode;
42: // PSTR pDeviceName;
43: // PNTPD pntpd;
44: //
45: // Given a pointer to a PSDEVMODE structure, a pointer to the current
46: // device name, and a pointer to the current NTPD structure, this routine
47: // fills in the default PSDEVMODE structure.
48: //
49: // History:
50: // 12-Dec-1992 -by- Kent Settle (kentse)
51: // Broke out of PSCRPTUI and PSCRIPT.
52: // 15-Apr-1992 -by- Kent Settle (kentse)
53: // Wrote it.
54: //--------------------------------------------------------------------------
55:
56: BOOL SetDefaultPSDEVMODE(pdevmode, pDeviceName, pntpd, hPrinter)
57: PSDEVMODE *pdevmode;
58: PWSTR pDeviceName;
59: PNTPD pntpd;
60: HANDLE hPrinter;
61: {
62: WCHAR FormName[CCHFORMNAME];
63: int i;
64: PSTR pstr;
65:
66: memset(pdevmode, 0, sizeof(PSDEVMODE));
67:
68: wcsncpy((PWSTR)&pdevmode->dm.dmDeviceName, pDeviceName, CCHDEVICENAME);
69:
70: pdevmode->dm.dmDriverVersion = DRIVER_VERSION;
71: pdevmode->dm.dmSpecVersion = DM_SPECVERSION;
72: pdevmode->dm.dmSize = sizeof(DEVMODE);
73: pdevmode->dm.dmDriverExtra = (sizeof(PSDEVMODE) - sizeof(DEVMODE));
74: pdevmode->dm.dmOrientation = DMORIENT_PORTRAIT;
75: pdevmode->dm.dmDuplex = DMDUP_SIMPLEX;
76: pdevmode->dm.dmCollate = DMCOLLATE_FALSE;
77: pdevmode->dm.dmTTOption = DMTT_SUBDEV;
78:
79: pstr = (CHAR *)pntpd + pntpd->loDefaultForm;
80: i = strlen(pstr) + 1;
81:
82: MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pstr, i, (LPWSTR)FormName, i);
83: wcsncpy((PWSTR)&pdevmode->dm.dmFormName, FormName, CCHFORMNAME);
84:
85: SetFormSize(hPrinter, pdevmode, FormName);
86:
87: pdevmode->dm.dmScale = 100;
88: pdevmode->dm.dmCopies = 1;
89:
90: pdevmode->dm.dmPrintQuality = (SHORT)pntpd->iDefResolution;
91:
92: if (pntpd->flFlags & COLOR_DEVICE)
93: pdevmode->dm.dmColor = DMCOLOR_COLOR;
94: else
95: pdevmode->dm.dmColor = DMCOLOR_MONOCHROME;
96:
97: pdevmode->dm.dmFields = DM_ORIENTATION | DM_PAPERSIZE | DM_SCALE |
98: DM_COPIES | DM_PRINTQUALITY | DM_COLOR |
99: DM_FORMNAME | DM_TTOPTION | DM_COLLATE;
100:
101: // state that we support duplex only if the printer really does.
102:
103: if ((pntpd->loszDuplexNone) || (pntpd->loszDuplexNoTumble) ||
104: (pntpd->loszDuplexTumble))
105: pdevmode->dm.dmFields |= DM_DUPLEX;
106:
107: // fill in default driver data.
108:
109: pdevmode->dwPrivDATA = PRIVATE_DEVMODE_ID;
110: pdevmode->dwFlags = PSDEVMODE_FONTSUBST;
111: pdevmode->coloradj = defcoloradj;
112:
113: return(TRUE);
114: }
115:
116:
117: //--------------------------------------------------------------------------
118: // BOOL ValidateSetDEVMODE(pdevmodeT, pdevmodeS, hPrinter, pntpd)
119: // PSDEVMODE *pdevmodeT;
120: // PSDEVMODE *pdevmodeS;
121: // HANDLE hPrinter;
122: // PNTPD pntpd;
123: //
124: // This routine validates any sources DEVMODE fields designated, and
125: // copies them to the target DEVMODE.
126: //
127: // Parameters
128: // pdevmodeT:
129: // Pointer to target DEVMODE.
130: //
131: // pdevmodeS:
132: // Pointer to source DEVMODE.
133: //
134: // hPrinter:
135: // Handle to the printer.
136: //
137: // pntpd:
138: // Pointer to printer descriptor NTPD structure.
139: //
140: // Returns
141: // This function returns TRUE if successful, FALSE otherwise.
142: //
143: // History:
144: // 14-Dec-1992 -by- Kent Settle (kentse)
145: // Moved from ..\pscript\enable.c, and generalized.
146: // 05-Aug-1991 -by- Kent Settle (kentse)
147: // Rewrote it.
148: // 24-Jan-1991 -by- Kent Settle (kentse)
149: // Wrote it.
150: //--------------------------------------------------------------------------
151:
152: BOOL ValidateSetDEVMODE(pdevmodeT, pdevmodeS, hPrinter, pntpd)
153: PSDEVMODE *pdevmodeT;
154: PSDEVMODE *pdevmodeS;
155: HANDLE hPrinter;
156: PNTPD pntpd;
157: {
158: int i;
159: PSRESOLUTION *pRes;
160: BOOL bDuplex, bFound;
161: DWORD cbNeeded, cReturned;
162: FORM_INFO_1 *pdbForm, *pdbForms;
163: PWSTR pwstrFormName;
164:
165: // verify a bunch of stuff in the DEVMODE structure. if each item
166: // selected by the user is valid, then set it in our DEVMODE
167: // structure.
168:
169: // if we have a NULL source, then we have nothing to do.
170:
171: if (pdevmodeS == (LPPSDEVMODE)NULL)
172: return(TRUE);
173:
174: // set the new orientation if its field is set, and the new
175: // orientation is valid.
176:
177: if (pdevmodeS->dm.dmFields & DM_ORIENTATION)
178: {
179: // validate the new orientation.
180:
181: if ((pdevmodeS->dm.dmOrientation != DMORIENT_PORTRAIT) &&
182: (pdevmodeS->dm.dmOrientation != DMORIENT_LANDSCAPE))
183: pdevmodeT->dm.dmOrientation = DMORIENT_PORTRAIT;
184: else
185: pdevmodeT->dm.dmOrientation = pdevmodeS->dm.dmOrientation;
186: }
187:
188: // if both the paper length and width fields are set and the
189: // corresponding values are valid, use these values to choose the
190: // form. if not, and the paper size field is set, use that value.
191: // if neither of these is used, check the form name.
192:
193: bFound = FALSE;
194:
195: if ((pdevmodeS->dm.dmFields & DM_PAPERLENGTH) &&
196: (pdevmodeS->dm.dmFields & DM_PAPERWIDTH))
197: {
198: if (!pdevmodeS->dm.dmPaperLength || !pdevmodeS->dm.dmPaperWidth)
199: {
200: pdevmodeT->dm.dmPaperLength = 0;
201: pdevmodeT->dm.dmPaperWidth = 0;
202: }
203: else
204: {
205: pdevmodeT->dm.dmPaperLength = pdevmodeS->dm.dmPaperLength;
206: pdevmodeT->dm.dmPaperWidth = pdevmodeS->dm.dmPaperWidth;
207: bFound = TRUE;
208: }
209: }
210:
211: // set the new paper size if its field is set.
212: //!!! should we have some type of size checking???
213:
214: if ((pdevmodeS->dm.dmFields & DM_PAPERSIZE) && (!bFound))
215: {
216: pdevmodeT->dm.dmPaperSize = pdevmodeS->dm.dmPaperSize;
217:
218: // protect ourselves.
219:
220: if ((pdevmodeT->dm.dmPaperSize < DMPAPER_FIRST) ||
221: (pdevmodeT->dm.dmPaperSize > DMPAPER_LAST))
222: pdevmodeT->dm.dmPaperSize = DMPAPER_FIRST;
223:
224: // we need to keep the formname and paper size index in sync.
225:
226: SetFormName(hPrinter, pdevmodeT, pdevmodeT->dm.dmPaperSize);
227: bFound = TRUE;
228: }
229:
230: // validate the form name.
231:
232: if ((pdevmodeS->dm.dmFields & DM_FORMNAME) && (!bFound))
233: {
234: pdbForms = (FORM_INFO_1 *)NULL;
235:
236: pwstrFormName = (PWSTR)pdevmodeS->dm.dmFormName;
237:
238: // enumerate the forms database to make sure the user supplied
239: // form is valid. if it cannot be found, set to the default.
240:
241: if (!EnumForms(hPrinter, 1, NULL, 0, &cbNeeded, &cReturned))
242: {
243: if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
244: {
245: if (pdbForms = (PFORM_INFO_1)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
246: cbNeeded))
247: {
248: if (EnumForms(hPrinter, 1, (LPBYTE)pdbForms,
249: cbNeeded, &cbNeeded, &cReturned))
250: {
251: // search each form in the database for a matching name,
252: // when it has been found, then search the forms supported
253: // by the printer to make sure the printer can print it.
254:
255: bFound = FALSE;
256: pdbForm = pdbForms;
257:
258: for (i = 0; i < (int)cReturned; i++)
259: {
260: if (!(wcscmp((PWSTR)pdbForm->pName, pwstrFormName)))
261: {
262: bFound = TRUE;
263: wcscpy((PWSTR)pdevmodeT->dm.dmFormName, pwstrFormName);
264: break;
265: }
266:
267: // search the next form in the database.
268:
269: pdbForm++;
270: }
271:
272: if (!bFound)
273: {
274: // could not find the user supplied name in
275: // the forms database, so set to default.
276:
277: strcpy2WChar((PWSTR)pdevmodeT->dm.dmFormName,
278: (CHAR *)pntpd + pntpd->loDefaultForm);
279: }
280: }
281: }
282: }
283: }
284: else
285: {
286: // could not find the user supplied name in
287: // the forms database, so set to default.
288:
289: strcpy2WChar((PWSTR)pdevmodeT->dm.dmFormName,
290: (CHAR *)pntpd + pntpd->loDefaultForm);
291: }
292:
293: // we need to keep the formname and paper size index in sync.
294:
295: SetFormSize(hPrinter, pdevmodeT, pdevmodeT->dm.dmFormName);
296:
297: if(pdbForms)
298: GlobalFree((HGLOBAL)pdbForms);
299: }
300:
301: if (pdevmodeS->dm.dmFields & DM_SCALE)
302: {
303: if ((pdevmodeS->dm.dmScale < MIN_SCALE) ||
304: (pdevmodeS->dm.dmScale > MAX_SCALE))
305: pdevmodeT->dm.dmScale = 100;
306: else
307: pdevmodeT->dm.dmScale = pdevmodeS->dm.dmScale;
308: }
309:
310: if (pdevmodeS->dm.dmFields & DM_COPIES)
311: {
312: if ((pdevmodeS->dm.dmCopies < MIN_COPIES) ||
313: (pdevmodeS->dm.dmCopies > MAX_COPIES))
314: pdevmodeT->dm.dmCopies = 1;
315: else
316: pdevmodeT->dm.dmCopies = pdevmodeS->dm.dmCopies;
317: }
318:
319: // update the print quality field, if it has been selected.
320: // this basically translates to resolution.
321:
322: if (pdevmodeS->dm.dmFields & DM_PRINTQUALITY)
323: {
324: // if cResolutions == 0, then only the default resolutions is valid.
325:
326: pdevmodeT->dm.dmPrintQuality = (SHORT)pntpd->iDefResolution;
327:
328: if ((pntpd->cResolutions > 0) && (pdevmodeS->dm.dmPrintQuality > 0))
329: {
330: // the current device supports multiple resolutions, so make
331: // sure that the user has selected one of them.
332:
333: pRes = (PSRESOLUTION *)((CHAR *)pntpd + pntpd->loResolution);
334:
335: for (i = 0; i < (int)pntpd->cResolutions; i++)
336: {
337: if ((pdevmodeS->dm.dmPrintQuality == (SHORT)pRes++->iValue))
338: {
339: // we did find it, so overwrite the default value.
340:
341: pdevmodeT->dm.dmPrintQuality = pdevmodeS->dm.dmPrintQuality;
342: break;
343: }
344: }
345: }
346: }
347:
348: // check the color flag.
349:
350: if (pdevmodeS->dm.dmFields & DM_COLOR)
351: {
352: // if the user has selected color on a color device print in color.
353: // otherwise print in monochrome.
354:
355: if ((pntpd->flFlags & COLOR_DEVICE) &&
356: (pdevmodeS->dm.dmColor == DMCOLOR_COLOR))
357: pdevmodeT->dm.dmColor = DMCOLOR_COLOR;
358: else
359: pdevmodeT->dm.dmColor = DMCOLOR_MONOCHROME;
360: }
361:
362: // check to see if the device handles duplex.
363:
364: if ((pntpd->loszDuplexNone) || (pntpd->loszDuplexNoTumble) ||
365: (pntpd->loszDuplexTumble))
366: bDuplex = TRUE;
367: else
368: bDuplex = FALSE;
369:
370: if (pdevmodeS->dm.dmFields & DM_DUPLEX)
371: {
372: if ((!(bDuplex)) ||
373: ((pdevmodeS->dm.dmDuplex != DMDUP_SIMPLEX) &&
374: (pdevmodeS->dm.dmDuplex != DMDUP_HORIZONTAL) &&
375: (pdevmodeS->dm.dmDuplex != DMDUP_VERTICAL)))
376: pdevmodeT->dm.dmDuplex = DMDUP_SIMPLEX;
377: else
378: pdevmodeT->dm.dmDuplex = pdevmodeS->dm.dmDuplex;
379: }
380:
381: if (pdevmodeS->dm.dmFields & DM_COLLATE)
382: {
383: if ((!(pntpd->loszCollateOn)) ||
384: ((pdevmodeS->dm.dmCollate != DMCOLLATE_TRUE) &&
385: (pdevmodeS->dm.dmCollate != DMCOLLATE_FALSE)))
386: pdevmodeT->dm.dmCollate = DMCOLLATE_FALSE;
387: else
388: pdevmodeT->dm.dmCollate = DMCOLLATE_TRUE;
389: }
390:
391: // handle the driver specific data. make sure it is ours.
392:
393: if ((pdevmodeS->dm.dmDriverExtra != 0) &&
394: (pdevmodeS->dwPrivDATA == PRIVATE_DEVMODE_ID))
395: {
396: pdevmodeT->dwPrivDATA = PRIVATE_DEVMODE_ID;
397: pdevmodeT->dwFlags = pdevmodeS->dwFlags;
398:
399: wcsncpy(pdevmodeT->wstrEPSFile, pdevmodeS->wstrEPSFile,
400: (sizeof(pdevmodeT->wstrEPSFile) / sizeof(WCHAR)));
401:
402: pdevmodeT->coloradj = pdevmodeS->coloradj;
403: }
404:
405: return(TRUE);
406: }
407:
408:
409:
410: //--------------------------------------------------------------------------
411: // VOID SetFormSize(pdevmode, FormName);
412: // PSDEVMODE *pdevmode;
413: // PWSTR FormName;
414: //
415: // This routine sets the dmPaperSize, dmPaperLength, and dmPaperWidth fields
416: // of the DEVMODE structure, based on FormName.
417: //
418: // Parameters
419: // pdevmode:
420: // Pointer to DEVMODE to be modified.
421: //
422: // FormName:
423: // UNICODE formname.
424: //
425: //
426: // Returns
427: // This function returns NO VALUE.
428: //
429: // Rewrote it.
430: // 22-Mar-1993 -by- Kent Settle (kentse)
431: // Wrote it.
432: //--------------------------------------------------------------------------
433:
434: VOID SetFormSize(hPrinter, pdevmode, FormName)
435: HANDLE hPrinter;
436: PSDEVMODE *pdevmode;
437: PWSTR FormName;
438: {
439: int iForm;
440: DWORD cbNeeded, cReturned;
441: FORM_INFO_1 *pdbForm, *pdbForms;
442: BOOL bFound;
443: SHORT Length, Width;
444:
445: // enumerate the forms database. then locate the index of the form
446: // within the database.
447:
448: pdbForms = (FORM_INFO_1 *)NULL;
449:
450: if (!EnumForms(hPrinter, 1, NULL, 0, &cbNeeded, &cReturned))
451: {
452: if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
453: {
454: if (pdbForms = (PFORM_INFO_1)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
455: cbNeeded))
456: {
457: if (EnumForms(hPrinter, 1, (LPBYTE)pdbForms,
458: cbNeeded, &cbNeeded, &cReturned))
459: {
460: // search the forms in the database. if the form is found
461: // within the first DMPAPER_LAST forms, then we have a
462: // predefined form, otherwise it is user defined.
463:
464: bFound = FALSE;
465: pdbForm = pdbForms;
466: cReturned = min(cReturned, DMPAPER_LAST);
467:
468: for (iForm = 1; iForm <= (int)cReturned; iForm++)
469: {
470: if (!(wcscmp((PWSTR)pdbForm->pName, FormName)))
471: {
472: // ah-ha! iForm is the index of the form.
473:
474: bFound = TRUE;
475: break;
476: }
477:
478: // search the next form in the database.
479:
480: pdbForm++;
481: }
482:
483: if (!bFound)
484: {
485: // must be a user defined form.
486:
487: iForm = DMPAPER_USER;
488: }
489: }
490: }
491: }
492: }
493:
494:
495: if (iForm == DMPAPER_USER)
496: {
497: // we have a user defined form. set the length and width of the
498: // form from the forms database. these are defined in .001mm in
499: // the database, and the DEVMODE wants .1mm.
500:
501: Length = pdbForm->Size.cy / 100;
502: Width = pdbForm->Size.cx / 100;
503: }
504: else
505: {
506: // iForm is already set properly, simply set the user width and
507: // length to zero.
508:
509: Length = 0;
510: Width = 0;
511: }
512:
513: pdevmode->dm.dmPaperSize = iForm;
514: pdevmode->dm.dmPaperLength = Length;
515: pdevmode->dm.dmPaperWidth = Width;
516:
517: if (pdbForms)
518: GlobalFree((HGLOBAL)pdbForms);
519: }
520:
521:
522: //--------------------------------------------------------------------------
523: // VOID SetFormSize(pdevmode, FormName);
524: // PSDEVMODE *pdevmode;
525: // PWSTR FormName;
526: //
527: // This routine sets the dmPaperSize, dmPaperLength, and dmPaperWidth fields
528: // of the DEVMODE structure, based on FormName.
529: //
530: // Parameters
531: // pdevmode:
532: // Pointer to DEVMODE to be modified.
533: //
534: // FormName:
535: // UNICODE formname.
536: //
537: //
538: // Returns
539: // This function returns NO VALUE.
540: //
541: // Rewrote it.
542: // 22-Mar-1993 -by- Kent Settle (kentse)
543: // Wrote it.
544: //--------------------------------------------------------------------------
545:
546: VOID SetFormName(hPrinter, pdevmode, iForm)
547: HANDLE hPrinter;
548: PSDEVMODE *pdevmode;
549: int iForm;
550: {
551: DWORD cbNeeded, cReturned;
552: FORM_INFO_1 *pdbForm, *pdbForms;
553: BOOL bSuccess;
554:
555: // if a user form is set then do nothing.
556:
557: if (iForm == DMPAPER_USER)
558: return;
559:
560: pdbForms = (FORM_INFO_1 *)NULL;
561: bSuccess = FALSE;
562:
563: // enumerate the forms database. then locate the index of the form
564: // within the database.
565:
566: if (!EnumForms(hPrinter, 1, NULL, 0, &cbNeeded, &cReturned))
567: {
568: if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
569: {
570: if (pdbForms = (PFORM_INFO_1)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
571: cbNeeded))
572: {
573: if (EnumForms(hPrinter, 1, (LPBYTE)pdbForms,
574: cbNeeded, &cbNeeded, &cReturned))
575: {
576: pdbForm = pdbForms;
577: pdbForm+= (iForm - 1);
578: bSuccess = TRUE;
579: }
580: }
581: }
582: }
583:
584: #if DBG
585: if (!bSuccess)
586: DbgPrint("PSCRIPT!_SetFormName: EnumForms failed.\n");
587: #endif
588:
589: // copy the form name into the DEVMODE structure.
590:
591: if (bSuccess)
592: wcsncpy(pdevmode->dm.dmFormName, pdbForm->pName, CCHFORMNAME);
593:
594: if (pdbForms)
595: GlobalFree((HGLOBAL)pdbForms);
596: }
597:
598:
599: DWORD
600: PickDefaultHTPatSize(
601: DWORD xDPI,
602: DWORD yDPI,
603: BOOL HTFormat8BPP
604: )
605:
606: /*++
607:
608: Routine Description:
609:
610: This function return default halftone pattern size used for a particular
611: device resolution
612:
613: Arguments:
614:
615: xDPI - Device LOGPIXELS X
616:
617: yDPI - Device LOGPIXELS Y
618:
619: 8BitHalftone - If a 8-bit halftone will be used
620:
621:
622: Return Value:
623:
624: DWORD HT_PATSIZE_xxxx
625:
626:
627: Author:
628:
629: 29-Jun-1993 Tue 14:46:49 created -by- Daniel Chou (danielc)
630:
631:
632: Revision History:
633:
634:
635: --*/
636:
637: {
638: DWORD HTPatSize;
639:
640: //
641: // use the smaller resolution as the pattern guide
642: //
643:
644: if (xDPI > yDPI) {
645:
646: xDPI = yDPI;
647: }
648:
649: if (xDPI >= 2400) {
650:
651: HTPatSize = HT_PATSIZE_16x16_M;
652:
653: } else if (xDPI >= 1800) {
654:
655: HTPatSize = HT_PATSIZE_14x14_M;
656:
657: } else if (xDPI >= 1200) {
658:
659: HTPatSize = HT_PATSIZE_12x12_M;
660:
661: } else if (xDPI >= 900) {
662:
663: HTPatSize = HT_PATSIZE_10x10_M;
664:
665: } else if (xDPI >= 400) {
666:
667: HTPatSize = HT_PATSIZE_8x8_M;
668:
669: } else if (xDPI >= 180) {
670:
671: HTPatSize = HT_PATSIZE_6x6_M;
672:
673: } else {
674:
675: HTPatSize = HT_PATSIZE_4x4_M;
676: }
677:
678: if (HTFormat8BPP) {
679:
680: HTPatSize -= 2;
681: }
682:
683: return(HTPatSize);
684: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.