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.

323 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1990-2003 Microsoft Corporation
  3. Module Name:
  4. forms.c
  5. Abstract:
  6. This module contains all functions related to the spooler/drivers forms
  7. Author:
  8. 18-Nov-1993 Thu 12:52:50 created
  9. [Environment:]
  10. GDI Device Driver - Plotter.
  11. [Notes:]
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #define DBG_PLOTFILENAME DbgForms
  17. #define DBG_ENUMFORMS 0x00000001
  18. #define DBG_ENUMFORMS2 0x00000002
  19. DEFINE_DBGVAR(0);
  20. #if DBG
  21. CHAR *pszFormMode[] = { " FORM_USER", "FORM_BUILTIN", "FORM_PRINTER" };
  22. #endif
  23. BOOL
  24. PlotEnumForms(
  25. HANDLE hPrinter,
  26. ENUMFORMPROC EnumFormProc,
  27. PENUMFORMPARAM pEnumFormParam
  28. )
  29. /*++
  30. Routine Description:
  31. This function enum all the forms from the spooler and return the
  32. FORM_INFO_1 arrary or using callback function to enum,
  33. this function automatically filter out the form size which greater then
  34. the device can support, it also set the valid bits if the device can
  35. handle the form in the data base.
  36. Arguments:
  37. hPrinter - Handler to the printer
  38. EnumFormProc - callback function, if NULL then no callback is performed
  39. pEnumFormParam - Pointer to the ENUMFORMPARAM data structure, the count
  40. and pFI1Base will be set upon returned.
  41. Return Value:
  42. BOOLEAN - if FALSE then a memory allocation or EnumForms() call failed
  43. Author:
  44. 18-Nov-1993 Thu 12:57:17 created
  45. 15-Dec-1993 Wed 21:14:46 updated
  46. Make the form valid if it rotated and can fit into the device
  47. 12-Jul-1994 Tue 12:43:50 updated
  48. Move PaperTray checking into here, so it will not call out if the paper
  49. cannot hold by paper tray.
  50. Revision History:
  51. --*/
  52. {
  53. PFORM_INFO_1 pFI1;
  54. DWORD Count;
  55. DWORD Index;
  56. DWORD cb;
  57. SIZEL DeviceSize;
  58. SIZEL MinSize;
  59. if (pEnumFormParam == NULL) {
  60. PLOTERR(("PlotEnumForms: invalid parameters"));
  61. return (FALSE);
  62. }
  63. pEnumFormParam->Count = 0;
  64. pEnumFormParam->ValidCount = 0;
  65. pEnumFormParam->pFI1Base = NULL;
  66. xEnumForms(hPrinter, 1, NULL, 0, &cb, &Count);
  67. if (xGetLastError() != ERROR_INSUFFICIENT_BUFFER) {
  68. PLOTERR(("PlotEnumForms: 1st EnumForms failed"));
  69. return(FALSE);
  70. }
  71. if (!(pFI1 = (PFORM_INFO_1)LocalAlloc(LPTR, cb))) {
  72. PLOTERR(("PlotEnumForms: LocalAlloc(%lu) failed", cb));
  73. return(FALSE);
  74. }
  75. if (!xEnumForms(hPrinter, 1, (LPBYTE)pFI1, cb, &cb, &Count)) {
  76. PLOTERR(("PlotEnumForms: 2nd EnumForms failed"));
  77. LocalFree((HLOCAL)pFI1);
  78. return(FALSE);
  79. }
  80. pEnumFormParam->Count = Count;
  81. pEnumFormParam->pFI1Base = pFI1;
  82. //
  83. // Firstable we will loop through the form to see if the form size is
  84. // smaller or equal to the the device size, if yes then set the
  85. // FI1F_VALID_SIZE bit
  86. //
  87. if (pEnumFormParam->pPlotGPC == NULL) {
  88. return (FALSE);
  89. }
  90. cb = 0;
  91. DeviceSize = pEnumFormParam->pPlotGPC->DeviceSize;
  92. MinSize.cx = pEnumFormParam->pPlotGPC->DeviceMargin.left +
  93. pEnumFormParam->pPlotGPC->DeviceMargin.right +
  94. MIN_PLOTGPC_FORM_CX;
  95. MinSize.cy = pEnumFormParam->pPlotGPC->DeviceMargin.top +
  96. pEnumFormParam->pPlotGPC->DeviceMargin.bottom +
  97. MIN_PLOTGPC_FORM_CY;
  98. PLOTASSERT(0, "Device Length too small (%ld)",
  99. DeviceSize.cy >= MIN_PLOTGPC_FORM_CY, DeviceSize.cy);
  100. PLOTDBG(DBG_ENUMFORMS2, ("\n---- PotEnumForm --Min=(%ld x %ld)-------------",
  101. MinSize.cx, MinSize.cy));
  102. if (MinSize.cx < MinSize.cy) {
  103. MinSize.cx = MinSize.cy;
  104. } else if (MinSize.cy < MinSize.cx) {
  105. MinSize.cy = MinSize.cx;
  106. }
  107. for (Index = 0; Index < Count; Index++) {
  108. //
  109. // The valid form means either straight or rotated form can be accepted
  110. // by the device.
  111. //
  112. pFI1->Flags &= ~FI1F_MASK;
  113. if ((pFI1->Size.cx >= MinSize.cx) &&
  114. (pFI1->Size.cy >= MinSize.cy) &&
  115. (((pFI1->Size.cx <= DeviceSize.cx) &&
  116. (pFI1->Size.cy <= DeviceSize.cy)) ||
  117. ((pFI1->Size.cy <= DeviceSize.cx) &&
  118. (pFI1->Size.cx <= DeviceSize.cy)))) {
  119. BOOL ValidForm = TRUE;
  120. DWORD FormMode;
  121. FormMode = pFI1->Flags & (FORM_USER | FORM_BUILTIN | FORM_PRINTER);
  122. if ((FormMode == FORM_BUILTIN) &&
  123. (((Index >= (DMPAPER_ENV_9 - DMPAPER_FIRST)) &&
  124. (Index <= (DMPAPER_ENV_14 - DMPAPER_FIRST))) ||
  125. ((Index >= (DMPAPER_ENV_DL - DMPAPER_FIRST)) &&
  126. (Index <= (DMPAPER_ENV_PERSONAL - DMPAPER_FIRST))) ||
  127. (Index == (DMPAPER_ENV_INVITE - DMPAPER_FIRST)))) {
  128. pFI1->Flags |= FI1F_ENVELOPE;
  129. } else if (FormMode == FORM_PRINTER) {
  130. PFORMSRC pFS;
  131. UINT i;
  132. CHAR bName[CCHFORMNAME];
  133. //
  134. // Check if this form is added by this driver
  135. //
  136. // Make sure that pFI1->pName is no longer than CCHFORMNAME.
  137. //
  138. if (wcslen(pFI1->pName) > CCHFORMNAME - 1) {
  139. ValidForm = FALSE;
  140. }
  141. else
  142. {
  143. WStr2Str(bName, CCHOF(bName), pFI1->pName);
  144. pFS = (PFORMSRC)pEnumFormParam->pPlotGPC->Forms.pData;
  145. i = (UINT)pEnumFormParam->pPlotGPC->Forms.Count;
  146. ValidForm = FALSE;
  147. while ((i--) && (!ValidForm)) {
  148. if (!strcmp(bName, pFS->Name)) {
  149. ValidForm = TRUE;
  150. }
  151. pFS++;
  152. }
  153. }
  154. }
  155. if ((ValidForm) &&
  156. (pEnumFormParam->pPlotGPC->Flags & PLOTF_PAPERTRAY) &&
  157. (pFI1->Size.cx != DeviceSize.cx) &&
  158. (pFI1->Size.cy != DeviceSize.cx)) {
  159. PLOTDBG(DBG_ENUMFORMS2,
  160. ("%s: %ld x %ld CANNOT hold by PAPER TRAY (%ld)",
  161. pFI1->pName, pFI1->Size.cx, pFI1->Size.cy,
  162. DeviceSize.cx));
  163. ValidForm = FALSE;
  164. }
  165. if (ValidForm) {
  166. pFI1->Flags |= FI1F_VALID_SIZE;
  167. ++cb;
  168. }
  169. PLOTDBG(DBG_ENUMFORMS2, ("%hs [-%hs-]: <%ws> (%ld x %ld)",
  170. pszFormMode[FormMode],
  171. (ValidForm) ? "Ok" : "--", pFI1->pName,
  172. pFI1->Size.cx, pFI1->Size.cy));
  173. }
  174. ++pFI1;
  175. }
  176. if (EnumFormProc) {
  177. //
  178. // In EnumFormProc it will increment ValidCount each time it called
  179. //
  180. if (pEnumFormParam->pCurForm) {
  181. DWORD cMaxOut;
  182. PLOTDBG(DBG_ENUMFORMS,
  183. ("PlotEnumForms: ValidCount=%ld, Count=%ld, cMaxOut=%ld",
  184. cb, Count, pEnumFormParam->cMaxOut));
  185. cb = 0;
  186. cMaxOut = pEnumFormParam->cMaxOut;
  187. pFI1 = pEnumFormParam->pFI1Base;
  188. for (Index = 0;
  189. ((Index <= Count) && (cMaxOut > 0));
  190. Index++, pFI1++, cMaxOut--) {
  191. if (Index == Count) {
  192. pFI1 = NULL;
  193. }
  194. if ((!pFI1) || (pFI1->Flags & FI1F_VALID_SIZE)) {
  195. ++cb;
  196. (*EnumFormProc)(pFI1, Index, pEnumFormParam);
  197. }
  198. }
  199. } else {
  200. //
  201. // Add a Custom Size Form
  202. //
  203. ++cb;
  204. }
  205. LocalFree((HLOCAL)pEnumFormParam->pFI1Base);
  206. pEnumFormParam->pFI1Base = NULL;
  207. }
  208. pEnumFormParam->ValidCount = cb;
  209. PLOTDBG(DBG_ENUMFORMS, ("PlotEnumForms: ValidCount = %ld / %ld",
  210. pEnumFormParam->ValidCount, pEnumFormParam->Count));
  211. return(TRUE);
  212. }