Jump to content

DEVESC_QUERYSIZE

From EDM2
Revision as of 00:13, 12 July 2025 by Martini (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

GreEscape DEVESC_QUERYSIZE queries the size of memory (in bytes) required for the corresponding list of specified job property types. Refer to Dynamic Job Properties for related information.

Simulation support
This function is mandatory for all drivers and must be implemented in order to have a valid OS/2 hardcopy driver.

Syntax

GreEscape(hdc, lEscape, cInCount, pInData, pcOutCount, pOutData, pInstance, lFunction);

Parameters

hdc (HDC) - input
Device context handle.
lEscape (LONG) - input
DEVESC_QUERYSIZE escape code.
cInCount (LONG) - input
Number of bytes pointed to by pInData.
pInData (PBYTE) - output
Pointer to the QUERYSIZE data structure.
hp2.Note:: pQuerySize->ulSizeNeeded is used as output.
pcOutCount (PLONG) - input
A pointer to the number of bytes pointed to by pOutData.
pOutData (PLONG) - input
Pointer to the printer driver's job properties.

This should be complete and not missing data or partially sized.

pInstance (PVOID) - input
Pointer to instance data.
lFunction (ULONG) - input
High-order WORD=flags; low-order WORD=NGreEscape.

Returns

rc (LONG) - returns
Return Code.

The handling routine returns:

DEV_OK
Successful.
DEV_PROP_BUF_TOO_SMALL
Job properties buffer did not have adequate space to contain the proper job properties data. The buffer will not be updated.
DEV_INV_INP_JOBPROPERTIES I
Invalid job properties were passed in. The driver changed them to default values. This is an error and the item buffer will not be updated.
DEVESC_ERROR
Error

Remarks

DEVESC_QUERYSIZE is used to determine the amount of buffer space necessary to query or set single or multiple job properties. Since DEVESC_QUERYSIZE is new, applications will call GreEscape DEVESC_QUERYESCSUPPORT to determine if you support this DevEscape.

This function has a handle to a device context (HDC) that should already have printer property information associated with the HDC. Job property information may change or may be dependent upon the printer property information in the HDC. In that case, if an application passes job properties for a different device or for a different spooler printer name, then misleading information will be returned. If a property is not supported, DEVESC_QUERYSIZE will allow space to hold the size of a simple DJP_ITEM structure. This space allows the next part of the process to continue without error. The application will be notified by GreEscape DEVESC_QUERYJOBPROPERTIES that the property is not supported.

Make sure to test the input job properties to make sure that they are valid. This includes passing tests such as whether they contain your driver's signature string, whether the device name is yours, and whether the values are within proper ranges (only landscape or portrait). If these tests fail, then fail the call.


Sample Code

Declaration:

#define INCL_DEV
#define INCL_DEVDJP
#include <os2.h>

HDC       hdc;       /* Device context handle. */
LONG      lEscape;   /* DEVESC_QUERYSIZE escape code. */
LONG      cInCount;  /* Number of bytes pointed to by pInData. */
PBYTE     pInData;   /* Pointer to the QUERYSIZE data structure. */
PLONG     pcOutCount;  /* A pointer to the number of bytes pointed to by pOutData. */
PLONG     pOutData;    /* Pointer to the printer driver's job properties. */
PVOID     pInstance;   /* Pointer to instance data. */
ULONG     lFunction;   /* High-order WORD=flags; low-order WORD=NGreEscape. */
LONG      rc;          /* Return Code. */

rc = GreEscape(hdc, lEscape, cInCount, pInData,
        pcOutCount, pOutData, pInstance, lFunction);

Sample:


LONG ENGENTRY Escape (HDC        hdc,
                      LONG       lEscape,
                      LONG       cInCount,
                      PBYTE      pInData,
                      PLONG      pcOutCount,
                      PBYTE      pOutData,
                      PDDC       pddc,
                      ULONG      ulFunction)
{
    switch (lEscape)
    {
    case DEVESC_QUERYSIZE:
    {
      INT          cbQueries  = cInCount;
      PQUERYSIZE   pQuerySize = (PQUERYSIZE)pInData;
      PQUERYTUPLE  pTuple     = pQuerySize->aTuples;
      INT          cbElmSize  = sizeof (QUERYTUPLE);
      INT          iCount;
      INT          iMaxCount;
      INT          iSize;

      if (GRE_234 > globals.ulGreVersion)
      {
          assertstring ("Not supported on pre-DAX engine!\n");
          lrc = DEVESC_NOTIMPLEMENTED;
          break;
      }

      pGoodDrivData = ReturnDriverData (pddc->pdb,
                                        pdi,
                                        pddc->pdb->hmcbHeap,
                                        pDrivData,
                                        pddc->pdb->pszPrinterName,
                                        TRUE,
                                        pDevice,
                                        pDriver);
      assertF (pGoodDrivData);

      /* Is the size of the input driver data is not the same as
      ** the size of our good data?
      */
      if (pDrivData->cb != pGoodDrivData->cb)
          lrc = DEV_PROP_BUF_TOO_SMALL;

      /* Or, if the two don't compare, then fail the call.
      */
      if (0 != memcmp (pDrivData, pGoodDrivData, pGoodDrivData->cb))
          lrc = DEV_INV_INP_JOBPROPERTIES;

      // Take off the header
      cbQueries -= QUERYSIZE_HEADER_SIZE;

      // Must be an even multiple
      assertT (cbQueries % cbElmSize);
      if (cbQueries % cbElmSize)
          break;

      // Initialize the returned size
      pQuerySize->ulSizeNeeded = 0;

      while (cbQueries)
      {
          switch (pTuple->ulProperty)
          {
          case DJP_NONE:
             iSize      = sizeof (((PDJP_ITEM)NULL)->ulValue);
             iMaxCount = 1;
             break;

          case DJP_SJ_ORIENTATION:
             iSize      = sizeof (DJPT_ORIENTATION);
             iMaxCount = 2;
             break;

          case DJP_CJ_RESOLUTION:
             iSize      = sizeof (DJPT_RESOLUTION);
             iMaxCount = pDevice->usNumRes;
             break;

          case DJP_SJ_BITSPERPEL:
             iSize      = sizeof (DJPT_BITSPERPEL);
             iMaxCount = pDevice->usNumPrintModes;
             break;

          case DJP_SJ_COLOR:
          {
             PPRINTMODE         pPrintMode    = pDriver->pPrintModes;
             ULONG              ulNumDefined  = pDriver->ulNumPrintModes;
             PULONG             pulPrintModes = pDevice->pulPrintModes;
             ULONG              ulNumDevice   = pDevice->usNumPrintModes;
             BOOL               fFoundMono    = FALSE,
                                fFoundColor   = FALSE;
             register INT       i, j;

             for (i = 0; i < ulNumDevice; i++)
             {
                for (j = 0; j < ulNumDefined; j++)
                {
                  if (pPrintMode[j].ulPrintModeID == pulPrintModes[i])
                  {
                      if (1 == pPrintMode[j].usBitsPerPel)
                          fFoundMono = TRUE;
                      else
                          fFoundColor = TRUE;
                  }
                }
             }

             iSize      = sizeof (DJPT_COLOR);
             iMaxCount = 0;
             if (fFoundMono)
                iMaxCount++;
             if (fFoundColor)
                iMaxCount++;
             if (!fFoundMono &&
                 !fFoundColor )
                iMaxCount = 1;
             break;
          }

          case DJP_CJ_FORM:
          case DJP_SJ_PAPERSIZE:
          {
             PUSERCONNECT pUserConn;
             ULONG        ulFormID,
                          ulTrayID,
                          ulMediaID;
             FORMINFO2    FormInfo;
             PTRAYINFO    pTrayInfo      = NULL;
             LONG         lRet;
             register INT i;

             iMaxCount = 0;

             switch (pTuple->ulProperty)
             {
             case DJP_CJ_FORM:
                iSize = sizeof (DJPT_FORM);
                break;

             case DJP_SJ_PAPERSIZE:
                iSize = sizeof (DJPT_PAPERSIZE);
                break;
             }

             for (i = 0; i < pDevice->usNumConnects; i++)
             {
                GetIDsFromConnID (pDriver,
                                  pDevice,
                                  pDevice->pulCONNECTS[i],
                                  &ulTrayID,
                                  &ulFormID,
                                  &ulMediaID);

                if (DJP_CJ_FORM == pTuple->ulProperty)
                {
                  iMaxCount++;
                }
                else if (DJP_SJ_PAPERSIZE == pTuple->ulProperty)
                {
                  lRet = GetDefaultFormInfo (pdb,
                                             ulFormID,
                                             pJobProp->ulDefResID,
                                             &FormInfo);

                  if (lRet)
                      lRet = FormInfo.ulDJPid;
                  else
                      lRet = DJP_PSI_NONE;

                  if (DJP_PSI_NONE != lRet)
                      iMaxCount++;
                }
             }

             // get pointer to first user-defined form connection
             pUserConn = pDevice->pUserDefData->pUserCONNECTS;

             // as long as we have user-defined form connections
             while (pUserConn)
             {
                if (DJP_CJ_FORM == pTuple->ulProperty)
                {
                  iMaxCount++;
                }
                else if (DJP_SJ_PAPERSIZE == pTuple->ulProperty)
                {
                  lRet = GetDefaultFormInfo (pdb,
                                             ulFormID,
                                             pJobProp->ulDefResID,
                                             &FormInfo);

                  if (lRet)
                      lRet = FormInfo.ulDJPid;
                  else
                      lRet = DJP_PSI_NONE;

                  if (DJP_PSI_NONE != lRet)
                      iMaxCount++;
                }

                // Move to the next connection
                pUserConn = pUserConn->pNextConnect;
             }

             if (0 == iMaxCount)
                // Make sure its at least 1
                iMaxCount = 1;
             break;
          }

          case DJP_SJ_COPIES:
             iSize      = sizeof (DJPT_COPIES);
             iMaxCount = 1;
             break;

          case DJP_SJ_PRINTQUALITY:
          case DJP_SJ_TRAYTYPE:
          case DJP_SJ_MEDIA:
          case DJP_SJ_MEDIA_COLOR:
          case DJP_CJ_MIXEDFORMS:
          case DJP_SJ_FONTDOWNLOADING:
          case DJP_SJ_DUPLEX:
          case DJP_SJ_COLLATE:
          case DJP_SJ_FEED:
          case DJP_SJ_SCALING:
          case DJP_SJ_FORMFEEDCONTROL:
          case DJP_SJ_N_UP:
          default:
             iSize         = sizeof (((PDJP_ITEM)NULL)->ulValue);
             iMaxCount     = 1;
             DBPRINTF (("Unknow query '%s' = %d!\n",
                          pszProperty (pTuple->ulProperty),
                          pTuple->ulProperty));
             break;
          }

          DBPRINTF (("Query size '%s'/%d = %d. Max count = %d\n",
                      pszProperty (pTuple->ulProperty),
                      pTuple->ulProperty,
                      iSize, iMaxCount));

          if (DJP_NONE    == pTuple->ulProperty ||
              DJP_CURRENT == pTuple->lType        )
          {
            iCount = 1;
          }
          else if (DJP_ALL == pTuple->lType)
          {
            iCount = iMaxCount;
          }
          else
          {
            iCount = 1;
            assertstring ("Unknown type!\n");
          }

          // Bump up the returned size
          pQuerySize->ulSizeNeeded += DJP_HEADER_SIZE + iCount * iSize;

          cbQueries -= cbElmSize;
          pTuple++;
      }

      // good result
      ulrc = DEV_OK;
      break;
    }
    }

    return lrc;
}