Leaked source code of windows server 2003
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.

464 lines
8.8 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. PPOINTS 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=NULL;
  55. DWORD cForms;
  56. DWORD result = 0;
  57. DRVDEVMODE dmCombinedDevMode;
  58. Verbose(("Entering DrvDeviceCapabilities: %d %x...\n", wCapability, pOutput));
  59. //
  60. // Do not execute any code before this initialization
  61. //
  62. if(!InitializeDll())
  63. {
  64. return GDI_ERROR;
  65. }
  66. //
  67. // Validate input devmode and combine it with driver default
  68. //
  69. ZeroMemory(&dmCombinedDevMode,sizeof(dmCombinedDevMode));
  70. GetCombinedDevmode(&dmCombinedDevMode, pdm, hPrinter, NULL, FALSE);
  71. result = 0;
  72. //
  73. // Return appropriate information depending upon wCapability
  74. //
  75. switch (wCapability) {
  76. case DC_VERSION:
  77. result = dmCombinedDevMode.dmPublic.dmSpecVersion;
  78. break;
  79. case DC_DRIVER:
  80. result = dmCombinedDevMode.dmPublic.dmDriverVersion;
  81. break;
  82. case DC_SIZE:
  83. result = dmCombinedDevMode.dmPublic.dmSize;
  84. break;
  85. case DC_EXTRA:
  86. result = dmCombinedDevMode.dmPublic.dmDriverExtra;
  87. break;
  88. case DC_FIELDS:
  89. result = dmCombinedDevMode.dmPublic.dmFields;
  90. break;
  91. case DC_COPIES:
  92. result = 1;
  93. break;
  94. case DC_ORIENTATION:
  95. //
  96. // Landscape rotates counterclockwise
  97. //
  98. result = 90;
  99. break;
  100. case DC_PAPERNAMES:
  101. case DC_PAPERS:
  102. case DC_PAPERSIZE:
  103. case DC_MINEXTENT:
  104. case DC_MAXEXTENT:
  105. //
  106. // Get a list of forms in the forms database
  107. //
  108. pFormsDB = GetFormsDatabase(hPrinter, &cForms);
  109. if (pFormsDB == NULL || cForms == 0) {
  110. Error(("Cannot get system forms\n"));
  111. return GDI_ERROR;
  112. }
  113. if (DC_MINEXTENT == wCapability ||
  114. DC_MAXEXTENT == wCapability)
  115. {
  116. DWORD dwCount = CalcMinMaxExtent((PPOINTS)&result, pFormsDB, cForms, wCapability);
  117. if (0 == dwCount)
  118. {
  119. result = GDI_ERROR;
  120. }
  121. }
  122. else
  123. {
  124. result = EnumPaperSizes(pOutput, pFormsDB, cForms, wCapability);
  125. }
  126. MemFree(pFormsDB);
  127. break;
  128. case DC_BINNAMES:
  129. //
  130. // Simulate a single input slot
  131. //
  132. if (pOutput)
  133. LoadString(g_hResource, IDS_SLOT_ONLYONE, pOutput, CCHBINNAME);
  134. result = 1;
  135. break;
  136. case DC_BINS:
  137. if (pOutput)
  138. *((PWORD) pOutput) = DMBIN_ONLYONE;
  139. result = 1;
  140. break;
  141. case DC_ENUMRESOLUTIONS:
  142. result = EnumResolutions(pOutput);
  143. break;
  144. default:
  145. Error(("Unknown device capability: %d\n", wCapability));
  146. result = GDI_ERROR;
  147. break;
  148. }
  149. return result;
  150. }
  151. DWORD
  152. EnumPaperSizes(
  153. PVOID pOutput,
  154. FORM_INFO_1 *pFormsDB,
  155. DWORD cForms,
  156. INT wCapability
  157. )
  158. /*++
  159. Routine Description:
  160. Retrieves a list of supported paper sizes
  161. Arguments:
  162. pOutput - Specifies a buffer for storing requested information
  163. pFormsDB - Pointer to an array of forms from the forms database
  164. cForms - Number of forms in the array
  165. wCapability - Specifies what the caller is interested in
  166. Return Value:
  167. Number of paper sizes supported
  168. --*/
  169. {
  170. DWORD index, count = 0;
  171. LPTSTR pPaperNames = NULL;
  172. PWORD pPapers = NULL;
  173. PPOINT pPaperSizes = NULL;
  174. //
  175. // Figure out what the caller is interested in
  176. //
  177. switch (wCapability) {
  178. case DC_PAPERNAMES:
  179. pPaperNames = pOutput;
  180. break;
  181. case DC_PAPERSIZE:
  182. pPaperSizes = pOutput;
  183. break;
  184. case DC_PAPERS:
  185. pPapers = pOutput;
  186. break;
  187. default:
  188. Assert(FALSE);
  189. }
  190. //
  191. // Go through each form in the forms database
  192. //
  193. for (index=0; index < cForms; index++, pFormsDB++) {
  194. //
  195. // If the form is supported on the printer, then increment the count
  196. // and collect requested information
  197. //
  198. if (! IsSupportedForm(pFormsDB))
  199. continue;
  200. count++;
  201. //
  202. // Return the size of the form in 0.1mm units.
  203. // The unit used in FORM_INFO_1 is 0.001mm.
  204. //
  205. if (pPaperSizes) {
  206. pPaperSizes->x = pFormsDB->Size.cx / 100;
  207. pPaperSizes->y = pFormsDB->Size.cy / 100;
  208. pPaperSizes++;
  209. }
  210. //
  211. // Return the formname.
  212. //
  213. if (pPaperNames) {
  214. CopyString(pPaperNames, pFormsDB->pName, CCHPAPERNAME);
  215. pPaperNames += CCHPAPERNAME;
  216. }
  217. //
  218. // Return one-based index of the form.
  219. //
  220. if (pPapers)
  221. *pPapers++ = (WORD) index + DMPAPER_FIRST;
  222. }
  223. return count;
  224. }
  225. DWORD
  226. CalcMinMaxExtent(
  227. PPOINTS pOutput,
  228. FORM_INFO_1 *pFormsDB,
  229. DWORD cForms,
  230. INT wCapability
  231. )
  232. /*++
  233. Routine Description:
  234. Retrieves the minimum or maximum paper size extent
  235. Arguments:
  236. pOutput - pointer to a POINTS structure
  237. pFormsDB - Pointer to an array of forms from the forms database
  238. cForms - Number of forms in the array
  239. wCapability - What the caller is interested in: DC_MAXEXTENT or DC_MINEXTENT
  240. Return Value:
  241. Number of paper sizes supported
  242. --*/
  243. {
  244. DWORD index, count = 0;
  245. LONG minX, minY, maxX, maxY;
  246. Assert (pOutput);
  247. //
  248. // Go through each form in the forms database
  249. //
  250. minX = minY = MAX_LONG;
  251. maxX = maxY = 0;
  252. for (index=0; index < cForms; index++, pFormsDB++) {
  253. //
  254. // If the form is supported on the printer, then increment the count
  255. // and collect the requested information
  256. //
  257. if (! IsSupportedForm(pFormsDB))
  258. {
  259. continue;
  260. }
  261. count++;
  262. if (minX > pFormsDB->Size.cx)
  263. {
  264. minX = pFormsDB->Size.cx;
  265. }
  266. if (minY > pFormsDB->Size.cy)
  267. {
  268. minY = pFormsDB->Size.cy;
  269. }
  270. if (maxX < pFormsDB->Size.cx)
  271. {
  272. maxX = pFormsDB->Size.cx;
  273. }
  274. if (maxY < pFormsDB->Size.cy)
  275. {
  276. maxY = pFormsDB->Size.cy;
  277. }
  278. }
  279. //
  280. // NOTE: What unit does the caller expect?! The documentation
  281. // doesn't mention anything about this. I assume this should
  282. // be in the same unit as DEVMODE.dmPaperLength, which is 0.1mm.
  283. //
  284. if (wCapability == DC_MINEXTENT)
  285. {
  286. pOutput->x = (SHORT)(minX / 100);
  287. pOutput->y = (SHORT)(minY / 100);
  288. }
  289. else
  290. {
  291. pOutput->x = (SHORT)(maxX / 100);
  292. pOutput->y = (SHORT)(maxY / 100);
  293. }
  294. return count;
  295. }
  296. DWORD
  297. EnumResolutions(
  298. PLONG pResolutions
  299. )
  300. /*++
  301. Routine Description:
  302. Retrieves a list of supported resolutions
  303. Arguments:
  304. pResolutions - Specifies a buffer for storing resolution information
  305. Return Value:
  306. Number of resolutions supported
  307. Note:
  308. Each resolution is represented by two LONGs representing
  309. horizontal and vertical resolutions (in dpi) respectively.
  310. --*/
  311. {
  312. if (pResolutions != NULL) {
  313. //
  314. // We support the following resolution settings:
  315. // Normal = 200x200 dpi
  316. // Draft = 200x100 dpi
  317. //
  318. *pResolutions++ = FAXRES_HORIZONTAL;
  319. *pResolutions++ = FAXRES_VERTICAL;
  320. *pResolutions++ = FAXRES_HORIZONTAL;
  321. *pResolutions++ = FAXRES_VERTDRAFT;
  322. }
  323. return 2;
  324. }