|
|
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.