Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

461 lines
8.5 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. devcaps.c
  5. Abstract:
  6. Implementation of DrvDeviceCapabilities
  7. Environment:
  8. Fax driver user interface
  9. Revision History:
  10. 01/09/96 -davidx-
  11. Created it.
  12. mm/dd/yy -author-
  13. description
  14. --*/
  15. #include "faxui.h"
  16. #include "forms.h"
  17. //
  18. // Forward declaration for local functions
  19. //
  20. DWORD
  21. CalcMinMaxExtent(
  22. PPOINT pOutput,
  23. FORM_INFO_1 *pFormsDB,
  24. DWORD cForms,
  25. INT wCapability
  26. );
  27. DWORD
  28. EnumResolutions(
  29. PLONG pResolutions
  30. );
  31. DWORD
  32. DrvDeviceCapabilities(
  33. HANDLE hPrinter,
  34. LPTSTR pDeviceName,
  35. WORD wCapability,
  36. PVOID pOutput,
  37. PDEVMODE pdm
  38. )
  39. /*++
  40. Routine Description:
  41. Provides information about the specified device and its capabilities
  42. Arguments:
  43. hPrinter - Identifies a printer object
  44. pDeviceName - Points to a null-terminated device name string
  45. wCapability - Specifies the interested device capability
  46. pOutput - Points to the output buffer
  47. pdm - Points to the source devmode structure
  48. Return Value:
  49. The return value depends on wCapability.
  50. Note:
  51. Please refer for DDK documentation for more details.
  52. --*/
  53. {
  54. FORM_INFO_1 *pFormsDB;
  55. DWORD cForms;
  56. PVOID pdmAlloced;
  57. DWORD result = 0;
  58. Verbose(("Entering DrvDeviceCapabilities: %d %x...\n", wCapability, pOutput));
  59. //
  60. // Validate input devmode and combine it with driver default
  61. //
  62. if (! (pdmAlloced = MemAlloc(sizeof(DRVDEVMODE)))) {
  63. Error(("Memory allocation failed\n"));
  64. return GDI_ERROR;
  65. }
  66. DriverDefaultDevmode(pdmAlloced, pDeviceName, hPrinter);
  67. pdm = pdmAlloced;
  68. result = 0;
  69. //
  70. // Return appropriate information depending upon wCapability
  71. //
  72. switch (wCapability) {
  73. case DC_VERSION:
  74. result = pdm->dmSpecVersion;
  75. break;
  76. case DC_DRIVER:
  77. result = pdm->dmDriverVersion;
  78. break;
  79. case DC_SIZE:
  80. result = pdm->dmSize;
  81. break;
  82. case DC_EXTRA:
  83. result = pdm->dmDriverExtra;
  84. break;
  85. case DC_FIELDS:
  86. result = pdm->dmFields;
  87. break;
  88. case DC_COPIES:
  89. //
  90. // Pretend that we can handle huge number of copies so that
  91. // the apps won't try to do multi-copies themselves.
  92. //
  93. result = 1000;
  94. break;
  95. case DC_ORIENTATION:
  96. //
  97. // Landscape rotates counterclockwise
  98. //
  99. result = 90;
  100. break;
  101. case DC_PAPERNAMES:
  102. case DC_PAPERS:
  103. case DC_PAPERSIZE:
  104. case DC_MINEXTENT:
  105. case DC_MAXEXTENT:
  106. //
  107. // Get a list of forms in the forms database
  108. //
  109. pFormsDB = GetFormsDatabase(hPrinter, &cForms);
  110. if (pFormsDB == NULL || cForms == 0) {
  111. Error(("Cannot get system forms\n"));
  112. return GDI_ERROR;
  113. }
  114. result = (wCapability == DC_MINEXTENT || wCapability == DC_MAXEXTENT) ?
  115. CalcMinMaxExtent(pOutput, pFormsDB, cForms, wCapability) :
  116. EnumPaperSizes(pOutput, pFormsDB, cForms, wCapability);
  117. MemFree(pFormsDB);
  118. break;
  119. case DC_BINNAMES:
  120. //
  121. // Simulate a single input slot
  122. //
  123. if (pOutput)
  124. LoadString(ghInstance, IDS_SLOT_ONLYONE, pOutput, CCHBINNAME);
  125. result = 1;
  126. break;
  127. case DC_BINS:
  128. if (pOutput)
  129. *((PWORD) pOutput) = DMBIN_ONLYONE;
  130. result = 1;
  131. break;
  132. case DC_ENUMRESOLUTIONS:
  133. result = EnumResolutions(pOutput);
  134. break;
  135. default:
  136. Error(("Unknown device capability: %d\n", wCapability));
  137. result = GDI_ERROR;
  138. break;
  139. }
  140. MemFree(pdmAlloced);
  141. return result;
  142. }
  143. DWORD
  144. EnumPaperSizes(
  145. PVOID pOutput,
  146. FORM_INFO_1 *pFormsDB,
  147. DWORD cForms,
  148. INT wCapability
  149. )
  150. /*++
  151. Routine Description:
  152. Retrieves a list of supported paper sizes
  153. Arguments:
  154. pOutput - Specifies a buffer for storing requested information
  155. pFormsDB - Pointer to an array of forms from the forms database
  156. cForms - Number of forms in the array
  157. wCapability - Specifies what the caller is interested in
  158. Return Value:
  159. Number of paper sizes supported
  160. --*/
  161. {
  162. DWORD index, count = 0;
  163. LPTSTR pPaperNames = NULL;
  164. PWORD pPapers = NULL;
  165. PPOINT pPaperSizes = NULL;
  166. //
  167. // Figure out what the caller is interested in
  168. //
  169. switch (wCapability) {
  170. case DC_PAPERNAMES:
  171. pPaperNames = pOutput;
  172. break;
  173. case DC_PAPERSIZE:
  174. pPaperSizes = pOutput;
  175. break;
  176. case DC_PAPERS:
  177. pPapers = pOutput;
  178. break;
  179. default:
  180. Assert(FALSE);
  181. }
  182. //
  183. // Go through each form in the forms database
  184. //
  185. for (index=0; index < cForms; index++, pFormsDB++) {
  186. //
  187. // If the form is supported on the printer, then increment the count
  188. // and collect requested information
  189. //
  190. if (! IsSupportedForm(pFormsDB))
  191. continue;
  192. count++;
  193. //
  194. // Return the size of the form in 0.1mm units.
  195. // The unit used in FORM_INFO_1 is 0.001mm.
  196. //
  197. if (pPaperSizes) {
  198. pPaperSizes->x = pFormsDB->Size.cx / 100;
  199. pPaperSizes->y = pFormsDB->Size.cy / 100;
  200. pPaperSizes++;
  201. }
  202. //
  203. // Return the formname.
  204. //
  205. if (pPaperNames) {
  206. CopyString(pPaperNames, pFormsDB->pName, CCHPAPERNAME);
  207. pPaperNames += CCHPAPERNAME;
  208. }
  209. //
  210. // Return one-based index of the form.
  211. //
  212. if (pPapers)
  213. *pPapers++ = (WORD) index + DMPAPER_FIRST;
  214. }
  215. return count;
  216. }
  217. DWORD
  218. CalcMinMaxExtent(
  219. PPOINT pOutput,
  220. FORM_INFO_1 *pFormsDB,
  221. DWORD cForms,
  222. INT wCapability
  223. )
  224. /*++
  225. Routine Description:
  226. Retrieves the minimum or maximum paper size extent
  227. Arguments:
  228. pOutput - Specifies a buffer for storing requested information
  229. pFormsDB - Pointer to an array of forms from the forms database
  230. cForms - Number of forms in the array
  231. wCapability - What the caller is interested in: DC_MAXEXTENT or DC_MINEXTENT
  232. Return Value:
  233. Number of paper sizes supported
  234. --*/
  235. {
  236. DWORD index, count = 0;
  237. LONG minX, minY, maxX, maxY;
  238. //
  239. // Go through each form in the forms database
  240. //
  241. minX = minY = MAX_LONG;
  242. maxX = maxY = 0;
  243. for (index=0; index < cForms; index++, pFormsDB++) {
  244. //
  245. // If the form is supported on the printer, then increment the count
  246. // and collect the requested information
  247. //
  248. if (! IsSupportedForm(pFormsDB))
  249. continue;
  250. count++;
  251. if (pOutput == NULL)
  252. continue;
  253. if (minX > pFormsDB->Size.cx)
  254. minX = pFormsDB->Size.cx;
  255. if (minY > pFormsDB->Size.cy)
  256. minY = pFormsDB->Size.cy;
  257. if (maxX < pFormsDB->Size.cx)
  258. maxX = pFormsDB->Size.cx;
  259. if (maxY < pFormsDB->Size.cy)
  260. maxY = pFormsDB->Size.cy;
  261. }
  262. //
  263. // If an output buffer is provided, store the calculated
  264. // minimum and maximum extent information.
  265. //
  266. if (pOutput != NULL) {
  267. //
  268. // NOTE: What unit does the caller expect?! The documentation
  269. // doesn't mention anything about this. I assume this should
  270. // be in the same unit as DEVMODE.dmPaperLength, which is 0.1mm.
  271. //
  272. if (wCapability == DC_MINEXTENT) {
  273. pOutput->x = minX / 100;
  274. pOutput->y = minY / 100;
  275. } else {
  276. pOutput->x = maxX / 100;
  277. pOutput->y = maxY / 100;
  278. }
  279. }
  280. return count;
  281. }
  282. DWORD
  283. EnumResolutions(
  284. PLONG pResolutions
  285. )
  286. /*++
  287. Routine Description:
  288. Retrieves a list of supported resolutions
  289. Arguments:
  290. pResolutions - Specifies a buffer for storing resolution information
  291. Return Value:
  292. Number of resolutions supported
  293. Note:
  294. Each resolution is represented by two LONGs representing
  295. horizontal and vertical resolutions (in dpi) respectively.
  296. --*/
  297. {
  298. if (pResolutions != NULL) {
  299. //
  300. // We support the following resolution settings:
  301. // Normal = 200x200 dpi
  302. // Draft = 200x100 dpi
  303. //
  304. *pResolutions++ = FAXRES_HORIZONTAL;
  305. *pResolutions++ = FAXRES_VERTICAL;
  306. *pResolutions++ = FAXRES_HORIZONTAL;
  307. *pResolutions++ = FAXRES_VERTDRAFT;
  308. }
  309. return 2;
  310. }