|
|
1.1 root 1: //--------------------------------------------------------------------------
2: //
3: // Module Name: DEVCAPS.C
4: //
5: // Brief Description: This module contains the PSCRIPT driver's Device
6: // capabilities function and related routines.
7: //
8: // Author: Kent Settle (kentse)
9: // Created: 16-Apr-1993
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: #include <winspool.h>
20: #include "dlgdefs.h"
21: #include "pscrptui.h"
22:
23: extern BOOL SetDefaultPSDEVMODE(PSDEVMODE *, PWSTR, PNTPD, HANDLE);
24: extern BOOL ValidateSetDEVMODE(PSDEVMODE *, PSDEVMODE *, HANDLE, PNTPD);
25: extern PFORM_INFO_1 GetFormsDataBase(HANDLE, DWORD *, PNTPD);
26:
27: extern TABLE_ENTRY PaperSourceTable[];
28:
29: #define CCHBINNAME 24 // characters allowed for bin name.
30: #define CCHPAPERNAME 64 // max length of form names.
31:
32: #define INITIAL_MIN_EXTENT 0x7FFFFFFF
33: #define INITIAL_MAX_EXTENT 0
34:
35: // form metrics in the forms database are in .001mm whereas we are to
36: // return them in .1mm units.
37:
38: #define FORMS01MM(a) ((a) / 100)
39:
40: // declarations of routines residing in this module.
41:
42: DWORD GetBinNumber(PSTR);
43:
44:
45: //--------------------------------------------------------------------------
46: // DWORD DrvDeviceCapabilities(hPrinter, pDeviceName, iDevCap, pvOutput, pDMIn)
47: // HANDLE hPrinter; /* Access to registry via spooler */
48: // PWSTR pDeviceName; /* Particular printer model name */
49: // WORD iDevCap; /* Capability required */
50: // void *pvOutput; /* Output area (for some) */
51: // DEVMODE *pdevmodeS; /* DEVMODE defining mode of operation etc */
52: //
53: // This routine returns the specified device's capabilities.
54: //
55: // This routine returns GDI_ERROR for failure, else depends on information requested.
56: //
57: // History:
58: // 16-Apr-1993 -by- Kent Settle (kentse)
59: // Wrote it, borrowed from RASDD.
60: //--------------------------------------------------------------------------
61:
62: DWORD DrvDeviceCapabilities(hPrinter, pDeviceName, iDevCap, pvOutput, pdevmodeS)
63: HANDLE hPrinter; // handle the to specific printer.
64: PWSTR pDeviceName; // what it says.
65: WORD iDevCap; // specific capability.
66: void *pvOutput; // output buffer.
67: DEVMODE *pdevmodeS; // source devmode.
68: {
69: PNTPD pntpd; // pointer to printer descriptor structure.
70: PSDEVMODE devmodeT; // target devmode.
71: DWORD dwRet; // the return value.
72: PSRESOLUTION *pRes; // pointer to our resolutions structures.
73: LONG *plOutput; // pointer to LONGs.
74: SHORT *psOutput; // pointer to SHORTs.
75: POINT *pptOutput; // pointer to POINTs.
76: WCHAR *pwchOutput; // pointer to WCHARs.
77: DWORD i; // counter.
78: DWORD count; // yac.
79: LONG lValue; // just a place holder.
80: PSINPUTSLOT *pslot; // pointer to PSINPUTSLOT structures.
81: PFORM_INFO_1 pdbForms; // pointer to PFORM_INFO_1 array.
82: PFORM_INFO_1 pdbForm; // pointer to PFORM_INFO_1 structure.
83: LONG lMaxX, lMinX; // places to calculate max/min extents.
84: LONG lMaxY, lMinY; // places to calculate max/min extents.
85:
86: // get a pointer to our printer descriptor structure.
87:
88: if (!(pntpd = MapPrinter(hPrinter)))
89: {
90: RIP("PSCRPTUI!DrvDeviceCapabilities: MapPrinter failed.\n");
91: return(GDI_ERROR);
92: }
93:
94: // fill in a default PSDEVMODE structure.
95:
96: if (!(SetDefaultPSDEVMODE(&devmodeT, pDeviceName, pntpd, hPrinter)))
97: {
98: RIP("PSCRPTUI!DrvDeviceCapabilities: SetDefaultPSDEVMODE failed.\n");
99: return(GDI_ERROR);
100: }
101:
102: // modify the default devmode if there is a user supplied one.
103:
104: if (pdevmodeS)
105: {
106: if (!(ValidateSetDEVMODE(&devmodeT, (PSDEVMODE *)pdevmodeS, hPrinter, pntpd)))
107: {
108: RIP("PSCRPTUI!DrvDeviceCapabilities: ValidateSetDEVMODE failed.\n");
109: return(GDI_ERROR);
110: }
111: }
112: // set up some handy pointers.
113:
114: psOutput = (SHORT *)pvOutput;
115: pptOutput = (POINT *)pvOutput;
116: pwchOutput = (WCHAR *)pvOutput;
117:
118: // we now have a valid devmodeT from which to work. so it is time to
119: // fill in the blanks.
120:
121: dwRet = 0;
122:
123: switch (iDevCap)
124: {
125: case DC_FIELDS:
126: dwRet = (DWORD)devmodeT.dm.dmFields;
127: break;
128:
129: case DC_PAPERS:
130: case DC_PAPERSIZE:
131: case DC_PAPERNAMES:
132: case DC_MINEXTENT:
133: case DC_MAXEXTENT:
134: // enumerate the forms database.
135:
136: if (!(pdbForms = GetFormsDataBase(hPrinter, &count, pntpd)))
137: {
138: RIP("PSCRPTUI!DrvDeviceCapabilities: GetFormsDataBase failed.\n");
139: return(GDI_ERROR);
140: }
141:
142: // for each form that is valid for the current printer, return the
143: // specified values to the caller.
144:
145: pdbForm = pdbForms;
146:
147: lMinX = INITIAL_MIN_EXTENT;
148: lMaxX = INITIAL_MAX_EXTENT;
149: lMinY = INITIAL_MIN_EXTENT;
150: lMaxY = INITIAL_MAX_EXTENT;
151:
152: for (i = 0; i < count; i++)
153: {
154: if (pdbForm->Flags & PSCRIPT_VALID_FORM)
155: {
156: // we have a form that is valid for this printer, so
157: // return the requested information.
158:
159: dwRet++;
160:
161: if (pvOutput)
162: {
163: switch (iDevCap)
164: {
165: case DC_PAPERS:
166: // return the index of the form.
167:
168: *psOutput++ = (SHORT)i + 1; // one based indicies.
169: break;
170:
171: case DC_PAPERSIZE:
172: // return the size of the form in .1mm units.
173:
174: pptOutput->x = FORMS01MM(pdbForm->Size.cx);
175: pptOutput->y = FORMS01MM(pdbForm->Size.cy);
176: pptOutput++;
177:
178: break;
179:
180: case DC_PAPERNAMES:
181: // return the formname.
182:
183: wcsncpy(pwchOutput, pdbForm->pName, CCHPAPERNAME);
184: pwchOutput += CCHPAPERNAME;
185:
186: break;
187:
188: case DC_MINEXTENT:
189: if (lMinX > pdbForm->Size.cx)
190: lMinX = pdbForm->Size.cx;
191:
192: if (lMinY > pdbForm->Size.cy)
193: lMinY = pdbForm->Size.cy;
194:
195: break;
196:
197: case DC_MAXEXTENT:
198: if (lMaxX < pdbForm->Size.cx)
199: lMaxX = pdbForm->Size.cx;
200:
201: if (lMaxY < pdbForm->Size.cy)
202: lMaxY = pdbForm->Size.cy;
203:
204: break;
205: }
206:
207: if (iDevCap == DC_MINEXTENT)
208: {
209: pptOutput->x = lMinX;
210: pptOutput->y = lMinY;
211: }
212:
213: if (iDevCap == DC_MAXEXTENT)
214: {
215: pptOutput->x = lMaxX;
216: pptOutput->y = lMaxY;
217: }
218: }
219: }
220:
221: // point to the next form.
222:
223: pdbForm++;
224: }
225:
226: break;
227:
228: case DC_BINS:
229: // get the count of input bins.
230:
231: count = pntpd->cInputSlots;
232:
233: if (pvOutput)
234: {
235: // if there is only one inputslot, the count may be zero.
236: // if so, use the default inputslot.
237:
238: if (count == 0)
239: *psOutput = (SHORT)GetBinNumber((CHAR *)pntpd +
240: pntpd->loDefaultSlot);
241: else
242: {
243: pslot = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);
244:
245: for (i = 0; i < count; i++)
246: {
247: // fill in the bin id number.
248:
249: //!!! need to handle > 1 user bins. -kentse.
250:
251: *psOutput++ = (SHORT)GetBinNumber((CHAR *)pntpd +
252: pslot->loSlotName);
253:
254: pslot++;
255: }
256: }
257: }
258:
259: if (count == 0)
260: count = 1;
261:
262: dwRet = count;
263:
264: break;
265:
266: case DC_BINNAMES:
267: // get the count of input bins.
268:
269: count = pntpd->cInputSlots;
270:
271: if (pvOutput)
272: {
273: // if there is only one inputslot, the count may be zero.
274: // if so, use the default inputslot.
275:
276: if (count == 0)
277: strcpy2WChar(pwchOutput, (CHAR *)pntpd + pntpd->loDefaultSlot);
278: else
279: {
280: pslot = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);
281:
282: for (i = 0; i < count; i++)
283: {
284: // fill in the bin name.
285:
286: strcpy2WChar(pwchOutput, (CHAR *)pntpd + pslot->loSlotName);
287:
288: pwchOutput += CCHBINNAME;
289:
290: pslot++;
291: }
292: }
293: }
294:
295: if (count == 0)
296: count = 1;
297:
298: dwRet = count;
299:
300: break;
301:
302: case DC_DUPLEX:
303: if ((pntpd->loszDuplexNone) || (pntpd->loszDuplexNoTumble) ||
304: (pntpd->loszDuplexTumble))
305: dwRet = 1;
306: else
307: dwRet = 0;
308: break;
309:
310: case DC_SIZE:
311: dwRet = (DWORD)devmodeT.dm.dmSize;
312: break;
313:
314: case DC_EXTRA:
315: dwRet = (DWORD)devmodeT.dm.dmDriverExtra;
316: break;
317:
318: case DC_VERSION:
319: dwRet = (DWORD)devmodeT.dm.dmSpecVersion;
320: break;
321:
322: case DC_DRIVER:
323: dwRet = (DWORD)devmodeT.dm.dmDriverVersion;
324: break;
325:
326: case DC_ENUMRESOLUTIONS:
327: // if there is an output buffer, fill it with supported resolutions.
328:
329: count = pntpd->cResolutions;
330:
331: if (pvOutput)
332: {
333: plOutput = pvOutput;
334:
335: // if there is only one resolution, the count will be zero.
336: // fill in the default resolution.
337:
338: if (count == 0)
339: {
340: lValue = (LONG)pntpd->iDefResolution;
341: *plOutput++ = lValue;
342: //!!! need to deal with anamorphic resolutions. - kentse.
343:
344: *plOutput = lValue;
345: }
346: else
347: {
348: pRes = (PSRESOLUTION *)((CHAR *)pntpd + pntpd->loResolution);
349:
350: for (i = 0; i < pntpd->cResolutions; i++)
351: {
352: lValue = (LONG)pRes->iValue;
353: *plOutput++ = lValue;
354: //!!! need to deal with anamorphic resolutions. - kentse.
355:
356: *plOutput++ = lValue;
357: pRes++;
358: }
359: }
360: }
361:
362: // if there is only one resolution, the count will be zero.
363: // fill in the default resolution.
364:
365: if (count == 0)
366: count = 1;
367:
368: dwRet = count;
369: break;
370:
371: case DC_FILEDEPENDENCIES:
372: // we are supposed to fill in an array of 64 character filenames,
373: // but, if we are to be of any use, we would need to use the
374: // fully qualified pathnames, and 64 characters is probably not
375: // enough.
376:
377: dwRet = 0;
378: if (pwchOutput)
379: *pwchOutput = (WCHAR)0;
380:
381: break;
382:
383: case DC_TRUETYPE:
384: if (!(devmodeT.dm.dmFields & DM_TTOPTION))
385: {
386: // truetype option not available, so blow it off.
387:
388: dwRet = 0;
389: break;
390: }
391:
392: #if defined(DCTT_DOWNLOAD) || defined(DCTT_BITMAP)
393: // we can do both.
394:
395: dwRet = DCTT_DOWNLOAD | DCTT_SUBDEV;
396: #else
397: // don't know what to return??? -kentse.
398:
399: dwRet = 0;
400: #endif
401: break;
402:
403: case DC_ORIENTATION:
404: dwRet = 90; // currently we only support 90 degree landscape.
405: break;
406:
407: case DC_COPIES:
408: dwRet = MAX_COPIES;
409: break;
410:
411: default:
412: dwRet = GDI_ERROR;
413: }
414:
415: return (dwRet);
416: }
417:
418:
419: //--------------------------------------------------------------------------
420: // DWORD GetBinNumber(pstrBin)
421: // PSTR pstrBin;
422: //
423: // This routine returns the windows bin id for the given bin name.
424: //
425: // History:
426: // 16-Apr-1993 -by- Kent Settle (kentse)
427: // Wrote it.
428: //--------------------------------------------------------------------------
429:
430: DWORD GetBinNumber(pstrBin)
431: PSTR pstrBin;
432: {
433: TABLE_ENTRY *ptable;
434:
435: ptable = PaperSourceTable;
436:
437: while (ptable->szStr)
438: {
439: if (!(strcmp(pstrBin, ptable->szStr)))
440: return(ptable->iValue);
441:
442: ptable++;
443: }
444:
445: // the bin was not one of the predefined ones.
446:
447: return(DMBIN_USER);
448: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.