/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark Corporation, 1989                                   */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = PRDMSUBR
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdm_WriteBodyData
 *             prdm_WriteIniEntry
 *             prdm_ReadBodyData
 *             prdm_ReadyDMData
 *             prdm_InitMainDlg
 *             prdm_FreeDMDataSegments
 *             prdm_LoadDMDataDefaults
 *             prdm_QueryMainBoxSelections
 *             prdm_InitSourceBoxes
 *             prdm_RadioButtonsControl
 *             prdm_FindFormInfo
 *             prdm_FindFormNumber
 *             prdm_FindDfltFormNo
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                        /* CON3201 */
#define INCL_DOSPROCESS                /* CON3201 */
#define INCL_WINHELP
#define INCL_DOSSEMAPHORES
#define INCL_GPIERRORS
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_DOSMODULEMGR
#define INCL_WINFRAMEMGR
#define INCL_WINLISTBOXES
#define INCL_WINBUTTONS
#define INCL_WINERRORS
#define INCL_WINDIALOGS
#define INCL_WINSHELLDATA
#define INCL_WINENTRYFIELDS
#define INCL_WINMESSAGEMGR
#define INCL_WININPUT
#define INCL_WINMENUS
#define INCL_WINWINDOWMGR
#define INCL_WINPOINTERS
#include <os2.h>
#undef INCL_DOSPROCESS                 /* CON3201 */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIERRORS
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_DOSMODULEMGR
#undef INCL_WINFRAMEMGR
#undef INCL_WINLISTBOXES
#undef INCL_WINBUTTONS
#undef INCL_WINERRORS
#undef INCL_WINDIALOGS
#undef INCL_WINSHELLDATA
#undef INCL_WINENTRYFIELDS
#undef INCL_WINMESSAGEMGR
#undef INCL_WININPUT
#undef INCL_WINMENUS
#undef INCL_WINWINDOWMGR
#undef INCL_WINPOINTERS
#undef INCL_WINHELP

#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#include <pmddi.h>
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS

#define INCL_WINP_SELSERVER
#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#include <pmwinx.h>
#undef INCL_WINP_SELSERVER
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_32                       /* CON3201 */

#define INCL_WINSHELLDATA
/* #include <pmshlp.h>                                              DLM01 */
#define INCL_WINSHELLDATA

#include <prdconse.h>
#include <prddcone.h>
#include <prdmcone.h>
#include <prdtcone.h>
#include <prdecone.h>                                     /* PD00657         */

#define NO_SYS
#define INCL_HELP
#define PRDMTYPE_INCL
#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL
#undef NO_SYS
#undef INCL_HELP
#undef PRDMTYPE_INCL

#include <prdgextf.h>
#include <prdmextf.h>
#include <prdeextf.h>
#include <prduextf.h>
#include <prdyextf.h>
#include <prdmtrcf.h>


/**********************************************************************/
/* Set up external accesses                                           */
/**********************************************************************/
extern DModeDataType       DMData;
extern lpDMSettings        pDMSettings;
extern CHAR                szCaption[40];
extern CHAR                szMessage[SLEN_BOX_MESSAGE];
extern DMIniEntryType      DMIniEntry[LARGEST_NO_OF_PRINTERS];

extern lpDDTType              DDT [];
extern lpDMSettings           DVTDfltDMSettings [];
extern DVTCPListType          DVTCodePageList [];
extern USHORT                 NO_OF_PRINTERS;
extern USHORT                 DRIVER_TYPE;
/*extern USHORT              prdd_ModHandle; CON3201 */
extern HMODULE                prdd_ModHandle;

extern szIBMQSTD[];
extern szIBMQRAW[];



#ifdef OMIT_OLD_CODE
/* CON3201 prdm_WriteHeaderData is no longer used, we will not convert to  */
/* CSet/2                                                                  */
/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_WriteHeaderData                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PBYTE            pDest          where to start writing to        */
/*   lpDMSettings     pDMSettings    what to write                    */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function writes the fixed length header data from           */
/*   DMSettings to the INI entry for the given printer.               */
/*                                                                    */
/**********************************************************************/
/*CON3201
//void pascal prdm_WriteHeaderData( pDest, pDMSettings )

PBYTE             pDest;
lpDMSettings      pDMSettings;
                               */
//void prdm_WriteHeaderData(PBYTE             pDest,
                            lpDMSettings      pDMSettings)

{
#define TFUNC "prdm_WriteHead"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT      Work;          /* Working word                        */
    USHORT      i;             /* Loop variable                       */

    /******************************************************************/
    /* Write the printer type code.                                   */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->PrinterType,
                            PRINTER_TYPE_LENGTH,
                            pDest );

    /******************************************************************/
    /* Write the total size of the entry for this printer.            */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->INIEntrySize,
                            NO_DATA_SIZE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the orientation.                                         */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->Orientation,
                            ORIENTATION_LENGTH,
                            pDest );

    /******************************************************************/
    /* Write the resolution.                                          */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->Resolution,
                            RESOLUTION_LENGTH,
                            pDest );

    /******************************************************************/
    /* Write the form feed state.                                     */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->FFSet,
                            FORM_FEED_LENGTH,
                            pDest );

    /******************************************************************/
    /* Write the default spool file type.                             */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->DefaultSpoolIndex,
                            SPOOL_INDEX_LENGTH,
                            pDest );

    /******************************************************************/
    /* Write the Pel Addressable font type.                           */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->PelAddrFontType) + '0';

    /******************************************************************/
    /* Write the index of the current Source configeration.           */
    /* This is an index into the DVTSourceList in the printer's DDT.  */
    /* The value held in the INI file for the two dual paper tray     */
    /* configerations on the Qs is a special case.   The same index   */
    /* is used for both (the one with no envelope tray); the          */
    /* current configeration then depends on the value in             */
    /* AddedFeed.                                                     */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->SourceIndex,
                            NO_INFO_SIZE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the Envelope Feed type.                                  */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->AddedFeed) + '0';

    /******************************************************************/
    /* Write the current form number.                                 */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->SelectedForm,
                            NO_FORM_CNT_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the number of forms.                                     */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->NumberOfForms,
                            NO_FORM_CNT_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the number of available cards.                           */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->NumberAvailCards,
                            NO_FONT_CNT_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the number of owned cards.                               */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->NumberOwnedCards,
                            NO_FONT_CNT_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the number of shipped cards.                             */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->ShippedCardCount,
                            NO_INFO_SIZE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the number of download fonts.                            */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->NumberOfDownFonts,
                            NO_FONT_CNT_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the flag indicating download code page memory available. */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->DownCPMemAvail) + '0';

    /******************************************************************/
    /* Write the number of added code pages.                          */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->NoOfAddedCPs,
                            NO_CODE_PAGE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the index of the initial code page - the index is into   */
    /* the DVTCodePageList.                                           */
    /******************************************************************/
    Work = pDMSettings->InitCodePage + 1;

    prdm_WriteTextFromWord( Work,
                            NO_CODE_PAGE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the reload type for the initial code page.               */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->InitCPReloadType) + '0';

    /******************************************************************/
    /* New fields MJB 30/10/90                                        */
    /******************************************************************/
    /******************************************************************/
    /* Memory option for the 4019 family                              */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->MemoryOption,
                            NO_MEM_OPT_DIGITS,
                            pDest );

    /******************************************************************/
    /* Resident font set: entry level or full set (might be needed    */
    /* on Heritage E)                                                 */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->ResFontSet) + '0';

    /******************************************************************/
    /* Printing mode on 3816: simplex, duplex or tumble duplex.       */
    /* Use DUPLEX_FLAG to indicate whether duplex option is enabled   */
    /* on the 4019 Heritage printer.                                  */
    /******************************************************************/
    Work = ( pDMSettings->SimDup +
             (pDMSettings->DuplexEnabled ? DUPLEX_FLAG : 0) ) + '0';
    *pDest++ = (BYTE)Work;

    /******************************************************************/
    /* Default source.                                                */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->DefaultSource,
                           NO_DEF_SOURCE_DIGITS,
                           pDest );

    /******************************************************************/
    /* Band compression.                                              */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->BandCompression) + '0';

    /******************************************************************/
    /* Down load system fonts.                                        */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->DownSysFonts) + '0';

    /******************************************************************/
    /* PD00136 : Disable outline fonts...                             */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->DisableOutlineFonts) + '0';

    /******************************************************************/
    /* DIAL/NILE : Write the MachineType.                             */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->MachineType) + '0';

    /******************************************************************/
    /* Write the default outline font point size     PD00137          */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->DfltFontPointSz,
                            NO_POINTSIZE_DIGITS,
                            pDest );

    /******************************************************************/
    /* PD00769 : Added Printer Patterns flag and shortened PADDING    */
    /* LENGTH by 1 byte to keep same length.                          */
    /******************************************************************/
    *pDest++ = (BYTE)(pDMSettings->PrinterPatterns) + '0';

    /******************************************************************/
    /* There are 4  unused bytes, reserved for future expansion.      */
    /* Note: we can't leave nulls in the .ini entry (null means end   */
    /* of the string), so write zeroes. prdm_WriteTextFromWord can't  */
    /* cope with fields of large length (e.g. 9 ) so do it manually.  */
    /******************************************************************/
    for ( i = PADDING_LENGTH; i; i--)
        *pDest++ = '0';

    /******************************************************************/
    /* That's all the new fields 30/10/90.                            */
    /******************************************************************/
    /******************************************************************/
    /* Write the size of the source form data.                        */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->SourceDataSize,
                            NO_DATA_SIZE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the length of the default metrics path.                  */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->MetricsPathLength,
                            PATHNAME_SIZE_LENGTH,
                            pDest );

    /******************************************************************/
    /* Write the size of the card data.                               */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->CardDataSize,
                            NO_DATA_SIZE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the size of the download font data.                      */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->DownFontDataSize,
                            NO_DATA_SIZE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the size of the code page data.                          */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->CodePageDataSize,
                            NO_DATA_SIZE_DIGITS,
                            pDest );

    /******************************************************************/
    /* Write the size of the default font info.                       */
    /******************************************************************/
    prdm_WriteTextFromWord( pDMSettings->DfltFontInfoSize,
                            NO_INFO_SIZE_DIGITS,
                            pDest );

}
#undef TFUNC

#endif




void prdm_ReadyDMData ()

{
#define TFUNC "prdm_ReadyDMDat"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT       i;           /* Loop control                         */

    /******************************************************************/
    /* Clear all the DMData structure pointers to Null.               */
    /******************************************************************/
    DMData.pCardData      = FNULL;
    DMData.Forms          = FNULL;
    DMData.OwnedIndexList = FNULL;
    DMData.pDownFontList  = FNULL;

    DMData.ConnsInfo.pManualPaper    = FNULL;
    DMData.ConnsInfo.pManualEnvelope = FNULL;
    DMData.DefaultFontList.DefaultFontTable = FNULL;

    DMData.pMetricsPath  = FNULL;
    DMData.pShippedCards = FNULL;

    for ( i = 0; i < NO_OF_ADDABLE_CPS; i++ )
        DMData.CPInfo.CPList[i].PathName = FNULL;

    /******************************************************************/
    /* Set the BodyData change flag to false.                         */
    /******************************************************************/
    DMData.BodyDataChanged = FALSE;
}
#undef TFUNC





void prdm_FreeDMDataSegments ()

{
#define TFUNC "prdm_FreeDMSegs"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT      i;            /* Loop control                         */
    psForm      Form;         /* Pointer to sForm structure           */
    psForm      NewForm;      /* Pointer to sForm structure           */

    /******************************************************************/
    /* Free all the segments used by DMData.                          */
    /******************************************************************/
    if ( DMData.pCardData )
/*      SSFREESEG(SELECTOROF( DMData.pCardData ));                   CON3201 */
        SSFREEMEM( DMData.pCardData );

    for ( Form = DMData.Forms; Form; Form = NewForm )
    {
        NewForm = Form->NextForm;
/*      SSFREESEG(SELECTOROF( Form ));                               CON3201 */
        SSFREEMEM(Form);
    }

    if ( DMData.OwnedIndexList )
/*      SSFREESEG(SELECTOROF( DMData.OwnedIndexList ));              CON3201 */
        SSFREEMEM(DMData.OwnedIndexList);

    if ( DMData.pDownFontList )
    {
        for ( i = 0; i < pDMSettings->NumberOfDownFonts; i++ )
/*          SSFREESEG(SELECTOROF( DMData.pDownFontList[i]));         CON3201 */
            SSFREEMEM(DMData.pDownFontList + i);

/*      SSFREESEG(SELECTOROF( DMData.pDownFontList ));               CON3201 */
        SSFREEMEM(DMData.pDownFontList);
    }

    if ( DMData.ConnsInfo.pManualPaper )
/*      SSFREESEG(SELECTOROF( DMData.ConnsInfo.pManualPaper ));      CON3201 */
        SSFREEMEM(DMData.ConnsInfo.pManualPaper );

    if ( DMData.ConnsInfo.pManualEnvelope )
/*      SSFREESEG(SELECTOROF( DMData.ConnsInfo.pManualEnvelope ));   CON3201 */
        SSFREEMEM(DMData.ConnsInfo.pManualEnvelope);

    if ( DMData.pMetricsPath )
/*      SSFREESEG(SELECTOROF( DMData.pMetricsPath );                 CON3201 */
        SSFREEMEM( DMData.pMetricsPath );

    if ( DMData.pShippedCards )
/*      SSFREESEG(SELECTOROF( DMData.pShippedCards ));               CON3201 */
        SSFREEMEM( DMData.pShippedCards );

    for ( i = 0; i < NO_OF_ADDABLE_CPS; i++ )
    {
        if ( DMData.CPInfo.CPList[i].PathName )
/*          SSFREESEG(SELECTOROF( DMData.CPInfo.CPList[i].PathName )); CON3201*/
            SSFREEMEM(DMData.CPInfo.CPList[i].PathName );
    }
}
#undef TFUNC





/*USHORT prdm_LoadDMDataDefaults (USHORT PrinterType ) CON3201 */
SHORT prdm_LoadDMDataDefaults (USHORT PrinterType )


{
#define TFUNC "prdm_LoadDMDflt"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
//  USHORT      Result;       /* Function call return values          */CON3201
    SHORT       Result;       /* Function call return values          */
    PBYTE       pSource;      /* Used to write default form data into */
                              /* our buffer when there is no entry in */
                              /* for the printer driver in OS2.INI    */
    SHORT       FormNum;      /* Loop control to fetch data on all    */
                              /* the defined forms                    */
    USHORT      i, j;         /* Loop control variables               */
    psForm      Form;         /* Pointer to sForm structure for       */
    psForm      NewForm;      /* constructing a linked list of these  */
    BYTE        CountryCode[4];  /* PD00812 : Country code            */


    /******************************************************************/
    /* Copy the default DM settings info across.                      */
    /******************************************************************/
    prdu_memcpy( (PBYTE)pDMSettings,
                 (PBYTE)DVTDfltDMSettings[PrinterType],
                 sizeof(DMSettingsType) );

    /******************************************************************/
    /* Put in the correct printer type and the default form info.     */
    /******************************************************************/
    pDMSettings->PrinterType  = PrinterType;
    pDMSettings->SelectedForm = DMData.DefaultForm;

    /******************************************************************/
    /* Put in the correct download code page memory availability      */
    /* information.                                                   */
    /* Note : 1. For Pro Printer (IBM42XX driver), if country is US   */
    /*           or Canada then "Memory Not Available"                */
    /*        2. Pro Printer XL has memory in machines world-wide.    */
    /*           So, it always has memory available.                  */
    /******************************************************************/
    if ( DDT[pDMSettings->PrinterType]->DDTDriverType == DDT_IBM42XX_DRV )
    {

        /**********************************************************************/
        /* PD00812 : Added code to read country code from INI and use it      */
        /* rather than SelectedForm to set DownCPMemAvail variable.           */
        /**********************************************************************/
//      if ( (pDMSettings->SelectedForm == DEFAULT_PAPER_FORM_US) &&
//           (pDMSettings->PrinterType != IBM_PRO_PRINTER_XL ) )
//      {
//          pDMSettings->DownCPMemAvail = DOWN_CP_MEM_NOT_AVAIL;
//      }

        (void) PrfQueryProfileString( HINI_USERPROFILE,
                                      "PM_National",
                                      "iCountry",
                                      "1",
                                      CountryCode,
                                      3 );

        if ( ( (CountryCode[0] == '1') && (CountryCode[1] == '\0') ) &&
             ( pDMSettings->PrinterType != IBM_PRO_PRINTER_XL ) )
        {
            pDMSettings->DownCPMemAvail = DOWN_CP_MEM_NOT_AVAIL;
        }

        /**************************************************************/
        /* DIAL/NILE :                                                */
        /* Set Extended NLS machine type for Nile/Tiber according to  */
        /* country:                                                   */
        /*      - US & Canada defaults to U.S.                        */
        /*      - All others defaults NLS.                            */
        /**************************************************************/

        /**********************************************************************/
        /*  PD00558 : Not all non-US, non-Canadian printers are NLS machines  */
        /*  so do not default to NLS for any country. Default value is set    */
        /*  up in DVTDfltDMSettings in prddmode.c now.                        */
        /**********************************************************************/
//      if (DDT[pDMSettings->PrinterType]->DDTFontFlags &
//                 DDT_NLS_FONTS_OPTIONAL)
//      {
//          if (pDMSettings->SelectedForm == DEFAULT_PAPER_FORM_US)
//          {
//              pDMSettings->MachineType = US_MACHINE;
//          }
//
//          else
//          {
//              pDMSettings->MachineType = NLS_MACHINE;
//          }
//      }
    }

    /******************************************************************/
    /* Set up the default DMData values for sources info.  The        */
    /* "+1" below is for tractor feed.                                */
    /******************************************************************/
    for ( i = 0; i < MAX_NO_OF_PAPER_TRAYS + 1; i++ )
        DMData.ConnsInfo.AutoTrayForm[i] = DMData.DefaultForm;

    /******************************************************************/
    /* Set default envelope based on country.                         */
    /******************************************************************/
    if ( DMData.DefaultForm == DEFAULT_PAPER_FORM_US )
        DMData.ConnsInfo.AutoTrayForm[CS_ENVELOPE_TRAY] =
                                           DEFAULT_ENVELOPE_FORM_US;
    else DMData.ConnsInfo.AutoTrayForm[CS_ENVELOPE_TRAY] =
                                        DEFAULT_ENVELOPE_FORM_NONUS;

    DMData.ConnsInfo.NoOfManualPaper = 0;
    DMData.ConnsInfo.NoOfManualEnv   = 0;

    /******************************************************************/
    /* Set up defaults for cards and the default font.                */
    /******************************************************************/
    DMData.FreeOwnedEntries = 0;

    for ( i = 0; i < MAX_NO_OF_CARD_SLOTS; i++ )
        DMData.Slot[i].Index = NO_CARD_IN_SLOT;

    DMData.DfltFontInfo.Info.Type = FT_RESIDENT;
    DMData.DfltFontInfo.Info.Index  = DDT[pDMSettings->
                                            PrinterType]->DDTDfltFontNo;

    pDMSettings->DfltFontInfoSize = DFLTFONT_RESIDENT_LEN;

    /******************************************************************/
    /* For every pre-defined form: Call SSALLOCSEG to get             */
    /* storage space for the data, set up a pointer to it either      */
    /* in DMData or in the NextForm field of the previous form        */
    /* definition and copy the data from our data segment.            */
    /******************************************************************/
    for ( FormNum = 0; FormNum < pDMSettings->NumberOfForms; FormNum++ )
    {
        /**************************************************************/
        /* Set NewForm to NULL here as SSALLOCSEG returns as a        */
        /* selector only and the offset must be zero.                 */
        /**************************************************************/
/*      Result = SSALLOCSEG (sizeof(sForm), &SELECTOROF(NewForm), 0); CON3201 */
        Result = SafeSSALLOCMEM ( &NewForm, sizeof(sForm), 0);

        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCSEG Fail", &Result, 1, Result);
            return ((USHORT)ERROR_ZERO);
        }

/*      OFFSETOF(NewForm) = 0;                                       CON3201 */

        if (!FormNum)
            DMData.Forms = NewForm;
        else
            Form->NextForm = NewForm;

        /**************************************************************/
        /* Advance Form to the last link in the current chain.        */
        /**************************************************************/
        Form = NewForm;
        Form->NextForm = FNULL;

        /**************************************************************/
        /* Set the form type and the form ID.                         */
        /**************************************************************/
        Form->FormType = DDT[PrinterType]->
                                 DDTDefinedForms[FormNum].FormType;
        Form->FormID   = DDT[PrinterType]->
                                 DDTDefinedForms[FormNum].FormId;

        /**************************************************************/
        /* Load the form name from the resource file (szMessage is    */
        /* used as a buffer here).                                    */
        /**************************************************************/
        WinLoadString( hab,
                       DMData.HModule,
                       DDT[PrinterType]->
                               DDTDefinedForms[FormNum].FormNameId,
                       SLEN_BOX_MESSAGE,
                       (PSZ)szMessage );

        /**************************************************************/
        /* Copy the form name into buffer and terminate with '\1'.    */
        /**************************************************************/
        pSource = szMessage;

        for ( i = 0; *pSource != '\0'; pSource++ )
        {
            Form->FormData[i++] = (*pSource == ALT_POINT)
                                     ? DMData.DecimalPoint : *pSource;
        }

        Form->FormData[i++] = '\1';

        /**************************************************************/
        /* Copy the form dimensions into our storage converting       */
        /* ALT_POINTs to the correct decimal point character.         */
        /**************************************************************/
        pSource = DDT[PrinterType]->DDTDefinedForms[FormNum].FormData;

        for ( j = 0; j < FORM_DIMS_LENGTH; j++, pSource++ )
        {
            Form->FormData[i++] = (*pSource == ALT_POINT)
                                     ? DMData.DecimalPoint : *pSource;
        }

        /**************************************************************/
        /* Pad the remainder of the memory allocated for the form     */
        /* data with spaces.                                          */
        /**************************************************************/
        while ( i < FORM_DATA_LENGTH )
        {
            Form->FormData[i++] = ' ';
        }
    }
    /*.. for (FormNum = 0; FormNum < ....every defined form.......... */

    /******************************************************************/
    /* Set the body data changed flag on to ensure memory for the     */
    /* INI entry for this printer is allocated before we attempt to   */
    /* write it.                                                      */
    /******************************************************************/
    DMData.BodyDataChanged = TRUE;

    return ((USHORT)OK);
}
#undef TFUNC



/**********************************************************************/
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/* PD00183 : Removed duplex querying code. That work is done in       */
/*           Prdm_ControlProc. Could do all of this work there and    */
/*           so tidy up this clumsy code                              */
/*                                                                    */
/**********************************************************************/

void prdm_QueryMainBoxSelections (HWND hwnd )


{
#define TFUNC "prdm_QryMainBox"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT       i;            /* Loop control                        */
    USHORT       BoxId;        /* Dialog box id                       */
    USHORT       BaseBoxId;    /* Dialog box id                       */
    lpDDTType    pDDT;         /* Pointer to DDT for this printer     */


    /******************************************************************/
    /* Some useful pointers                                           */
    /******************************************************************/
    pDDT = DDT[pDMSettings->PrinterType];

    /******************************************************************/
    /* Read the current resolution.                                   */
    /******************************************************************/
    if ( pDDT->DDTDialogFlags & DDT_RADIO_RESOLUTION )
    {
        if ( WinSendDlgItemMsg( hwnd,
                                DB_RAD_PPRES0,
                                BM_QUERYCHECK,
                                FNULL,
                                FNULL))
        {
            pDMSettings->Resolution = 0;
        }
        else if ( WinSendDlgItemMsg( hwnd,
                                     DB_RAD_PPRES1,
                                     BM_QUERYCHECK,
                                     FNULL,
                                     FNULL))
        {
            pDMSettings->Resolution = 1;
        }
        else if ( WinSendDlgItemMsg( hwnd,
                                     DB_RAD_PPRES3,
                                     BM_QUERYCHECK,
                                     FNULL,
                                     FNULL))
        {
            pDMSettings->Resolution = 3;
        }
        else
        {
            pDMSettings->Resolution = 2;
        }
    }
    else
    {
        pDMSettings->Resolution = (USHORT)WinSendDlgItemMsg(
                                                 hwnd,
                                                 DB_LST_PPRESOLUTION,
                                                 LM_QUERYSELECTION,
                                                 (MPARAM)(ULONG)LIT_FIRST,
                                                 FNULL);
    }

    /******************************************************************/
    /* The current form number is kept up to data so next get the     */
    /* current paper orientation.                                     */
    /******************************************************************/
    if ( WinSendDlgItemMsg( hwnd,
                            DB_RAD_PPPORTRAIT,
                            BM_QUERYCHECK,
                            FNULL,
                            FNULL) )
    {
        pDMSettings->Orientation = PORTRAIT;
    }
    else
    {
        pDMSettings->Orientation = LANDSCAPE;
    }


    /******************************************************************/
    /* Determine which form feed option has been selected.            */
    /******************************************************************/
    if ( pDDT->DDTFormFlags & DDT_VAR_FORM_FEED_CONTROL )
    {
        if ( WinSendDlgItemMsg( hwnd,
                                DB_RAD_FF_NONE,
                                BM_QUERYCHECK, FNULL, FNULL) )
        {
            pDMSettings->FFSet = FF_NONE_MODE;
        }
        else if ( WinSendDlgItemMsg( hwnd,
                                     DB_RAD_FF_COMPULSORY,
                                     BM_QUERYCHECK, FNULL, FNULL) )
        {
            pDMSettings->FFSet = FF_COMPULSORY_MODE;
        }
        else
        {
            pDMSettings->FFSet = FF_CONDITIONAL_MODE;
        }
    }
    else
    {
        /**************************************************************/
        /* Make sure that conditional foomfeed processing is used     */
        /* for printers without user FF control.                      */
        /**************************************************************/
        pDMSettings->FFSet = FF_CONDITIONAL_MODE;
    }

    /******************************************************************/
    /* Get the pel-addressable/printer fonts available type.          */
    /*                                                                */
    /* PD00604 : We now have some printers which have three buttons   */
    /* in the printer fonts box.  Set PelAddrFontType depending       */
    /* on a dialog flag.                                              */
    /******************************************************************/
    if ( pDDT->DDTDialogFlags & DDT_LIMIT_FONTS)
    {
        if ( WinSendDlgItemMsg( hwnd,
                                DB_RAD_FONTS_OFF,
                                BM_QUERYCHECK,
                                FNULL,
                                FNULL) )
        {
            pDMSettings->PelAddrFontType = DEV_FONTS_NOT_AVAIL;
        }
        else if ( WinSendDlgItemMsg( hwnd,
                                     DB_RAD_FONTS_LIMITED,
                                     BM_QUERYCHECK,
                                     FNULL,
                                     FNULL) )
        {
            pDMSettings->PelAddrFontType = DEV_FONTS_LIMITED;
        }
        else
        {
            pDMSettings->PelAddrFontType = DEV_FONTS_AVAIL_2;
        }
    }
    else
    {
        if ( WinSendDlgItemMsg( hwnd,
                                DB_RAD_FONTS_OFF,
                                BM_QUERYCHECK,
                                FNULL,
                                FNULL) )
        {
            pDMSettings->PelAddrFontType = DEV_FONTS_NOT_AVAIL;
        }
        else
        {
            pDMSettings->PelAddrFontType = DEV_FONTS_AVAIL;
        }
    }

    /******************************************************************/
    /* Read the default spool type from the listbox.                  */
    /******************************************************************/
    pDMSettings->DefaultSpoolIndex = (USHORT)WinSendDlgItemMsg(
                                             hwnd,
                                             DB_LST_SPOOL_FILE,
                                             LM_QUERYSELECTION,
                                             (MPARAM)(ULONG)LIT_FIRST,
                                             FNULL);

//  /******************************************************************/
//  /* Check if code pages are supported for this printer.            */
//  /******************************************************************/
//  if ( (pDDT->DDTFontFlags & DDT_ADD_CODE_PAGE_SUPPORT) &&
//       !(pDDT->DDTFontFlags & DDT_CODE_PAGE_NOTOPTION) )
//  {
//      /**************************************************************/
//      /* Determine the state of the downloadable code page          */
//      /* memory availability.                                       */
//      /**************************************************************/
//      if ( SHORT1FROMMR(WinSendDlgItemMsg( hwnd,
//                                           DB_RAD_CPMEM_YES,
//                                           BM_QUERYCHECK,
//                                           FNULL,
//                                           FNULL )) )
//      {
//          pDMSettings->DownCPMemAvail = DOWN_CP_MEM_AVAIL;
//      }
//      else
//      {
//          pDMSettings->DownCPMemAvail = DOWN_CP_MEM_NOT_AVAIL;
//      }
//  }
//
//  /******************************************************************/
//  /* Query duplex support. Default to disabled.                     */
//  /******************************************************************/
//  pDMSettings->DuplexEnabled = FALSE;
//
//  if ( pDDT->DDTSourceFlags & DDT_DUPLEX_OPTIONAL )
//  {
//      if ( WinSendDlgItemMsg( hwnd,
//                              DB_RAD_DUP_ENABLED,
//                              BM_QUERYCHECK,
//                              FNULL,
//                              FNULL ) )
//      {
//          pDMSettings->DuplexEnabled = TRUE;
//      }
//  }
//
//  /******************************************************************/
//  /* Query the duplex option setting, if enabled/present.           */
//  /******************************************************************/
//
//  if ( (( pDDT->DDTSourceFlags & DDT_DUPLEX_OPTIONAL ) &&
//          pDMSettings->DuplexEnabled) ||
//       (pDDT->DDTSourceFlags & DDT_DUPLEX_SUPPORT) )
//  {
//      pDMSettings->SimDup = 0;
//      for ( i = 0 ; i < 3 ; i ++ )
//      {
//          if ( WinSendDlgItemMsg( hwnd,
//                                  DB_RAD_SIMPLEX + i,
//                                  BM_QUERYCHECK,
//                                  FNULL,
//                                  FNULL ) )
//          {
//              pDMSettings->SimDup = i;
//          }
//      }
//  }

    return;
}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_WriteBodyData                                     */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   USHORT    PrinterType   Printer type code                        */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function writes the variable length body data from          */
/*   DMData to the INI entry for the given printer.                   */
/*                                                                    */
/**********************************************************************/
void prdm_WriteBodyData(USHORT PrinterType )

{
#define TFUNC "prdm_WriteBody"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    PBYTE       pDest;         /* Working pointer                     */
    PBYTE       pSource;       /* Working pointer                     */
    USHORT      i, j;          /* Loop variables                      */
    psForm      Form;          /* Pointer to sForm structure          */
    USHORT      Work;          /* Temporary working variable          */
    USHORT      PathNameSize;  /* For download fonts                  */


    /******************************************************************/
    /* Set the working pointer to the address of the variable length  */
    /* data in the INI entry for the given printer.                   */
    /******************************************************************/
    pDest = DMIniEntry[PrinterType].Data + HEADER_LENGTH;
    TRACE6(TFUNC, "Start of Form data", pDest, 8);

    /******************************************************************/
    /* Copy all the form definition data into the buffer (turning     */
    /* decimal points into ALT_POINTs).                               */
    /******************************************************************/
    for ( Form = DMData.Forms; Form; Form = Form->NextForm )
    {
        /**************************************************************/
        /* Write the form type and form ID.                           */
        /**************************************************************/
        *pDest++ = Form->FormType;
        *pDest++ = Form->FormID;

        pSource = Form->FormData;
        for ( i = 0; i < FORM_DATA_LENGTH; i++, pSource++ )
        {
            *pDest++ = (*pSource == DMData.DecimalPoint) ?
                                                  ALT_POINT : *pSource;
        }
    }

    TRACE6(TFUNC, "Written form info", FNULL, 0);

    if ( pDMSettings->SourceDataSize )
    {
        TRACE6(TFUNC, "Write source data", FNULL, 0);

        /**************************************************************/
        /* Write the form numbers mounted in automatic trays as text. */
        /**************************************************************/
        for ( i = 0; i < NO_OF_AUTO_TRAYS; i++ )
        {
            prdm_WriteTextFromWord( DMData.ConnsInfo.AutoTrayForm[i],
                                    NO_FORM_CNT_DIGITS,
                                    pDest );
        }

        /**************************************************************/
        /* Write the number of manual paper forms and the numbers     */
        /**************************************************************/
        prdm_WriteTextFromWord( DMData.ConnsInfo.NoOfManualPaper,
                                NO_FORM_CNT_DIGITS,
                                pDest );

        for ( i = 0; i < DMData.ConnsInfo.NoOfManualPaper; i++ )
        {
            prdm_WriteTextFromWord( DMData.ConnsInfo.pManualPaper[i],
                                    NO_FORM_CNT_DIGITS,
                                    pDest );
        }

        /**************************************************************/
        /* Write number of manual envelope forms and the numbers      */
        /**************************************************************/
        prdm_WriteTextFromWord( DMData.ConnsInfo.NoOfManualEnv,
                                NO_FORM_CNT_DIGITS,
                                pDest );

        for ( i = 0; i < DMData.ConnsInfo.NoOfManualEnv; i++ )
        {
            prdm_WriteTextFromWord( DMData.ConnsInfo.pManualEnvelope[i],
                                    NO_FORM_CNT_DIGITS,
                                    pDest );
        }
    }


    /******************************************************************/
    /* Copy all the owned card indices as text into the buffer.       */
    /* The indices are into the list of all available cards (i.e. all */
    /* shipped + added cards).                                        */
    /******************************************************************/
    for ( i = 0; i < pDMSettings->NumberOwnedCards; i++ )
    {
        prdm_WriteTextFromWord( DMData.OwnedIndexList[i],
                                NO_FONT_CNT_DIGITS,
                                pDest );
    }

    /******************************************************************/
    /* Write the indices of the cards in the slots.                   */
    /* These indices are into the list of owned cards.                */
    /* Always add one so that case when no card is selected           */
    /* (index is -1) the value will be stored as zero                 */
    /******************************************************************/
    for ( i = 0; i < MAX_NO_OF_CARD_SLOTS; i++ )
    {
        prdm_WriteTextFromWord( (DMData.Slot[i].Index + 1),
                                NO_INDEX_DIGITS,
                                pDest );
    }

    /******************************************************************/
    /* Copy all the shipped card names into buffer (turning null      */
    /* values into spaces) - each name will take up 9 characters.     */
    /******************************************************************/
    for ( i = 0, pSource = (PBYTE)DMData.pShippedCards;
          i < (pDMSettings->ShippedCardCount * sizeof(tCard));
          i++, pSource++ )
    {
        *pDest++ = (*pSource == '\0') ? (BYTE)' ' : *pSource;
    }

    /******************************************************************/
    /* Copy all the card data into the buffer (turning null values    */
    /* into spaces).  This data is the full pathname of all the       */
    /* added cards - the entries will be seperated by spaces.  The    */
    /* total length of this data is given by CardDatasize in the      */
    /* header info.                                                   */
    /******************************************************************/
    for ( i = 0, pSource = DMData.pCardData;
          i < pDMSettings->CardDataSize;
          i++, pSource++ )
    {
        *pDest++ = (*pSource == '\0') ? (BYTE)' ' : *pSource;
    }


    /******************************************************************/
    /* Cycle through the fonts in the download font list and copy     */
    /* the data into the buffer.                                      */
    /******************************************************************/
    for ( i = 0; i < pDMSettings->NumberOfDownFonts; i++ )
    {
        /**************************************************************/
        /* Set the source pointer.                                    */
        /**************************************************************/
        pSource = DMData.pDownFontList[i].DownloadInfo;

        /**************************************************************/
        /* Get the size of the pathname so we know how much           */
        /* data to copy.  Note that pSource is not incremented here   */
        /* so the macro prdm_ReadWordFromtext is not used.            */
        /**************************************************************/
        PathNameSize = 0;
        for ( j = 0; j < PATHNAME_SIZE_LENGTH; j++)
        {
            PathNameSize *= 10;
            PathNameSize += pSource[j] - '0';
        }

        /**************************************************************/
        /* Copy across the download info (except type & filesize)     */
        /* i.e. pathname size, path, space, name, space,              */
        /* typeface, codepage, pointsize.                             */
        /**************************************************************/
        for ( j = 0; j < PathNameSize + DM_DOWN_FXD_LENGTH; j++ )
        {
            *pDest++ = *pSource++;
        }

        /**************************************************************/
        /* Copy the download type (initial or dynamic)                */
        /**************************************************************/
        *pDest++ = DMData.pDownFontList[i].DownloadType;

        /**************************************************************/
        /* Write the font file size.  The high word is written        */
        /* as three text characters; then the low word as five.       */
        /**************************************************************/
        Work = (((PUSHORT)&(DMData.pDownFontList[i].DownloadSize))[1]);
        prdm_WriteTextFromWord( Work, 3, pDest );

        Work = (((PUSHORT)&(DMData.pDownFontList[i].DownloadSize))[0]);
        prdm_WriteTextFromWord( Work, 5, pDest );
    }

    /******************************************************************/
    /* Copy the info for the added downloadable code pages.           */
    /******************************************************************/
    for ( i = 0; i < NO_OF_ADDABLE_CPS; i++ )
    {
        /**************************************************************/
        /* If the pathname is not null then copy the info for this    */
        /* code page to the INI entry.                                */
        /**************************************************************/
        if ( DMData.CPInfo.CPList[i].PathName )
        {
            /**********************************************************/
            /* Write the code page index and the pathname size; the   */
            /* code page number is an index into the DVTCodePageList  */
            /* array.                                                 */
            /**********************************************************/
            Work = i + 2;

            prdm_WriteTextFromWord( Work,
                                    NO_CODE_PAGE_DIGITS,
                                    pDest );

            prdm_WriteTextFromWord( DMData.CPInfo.CPList[i].PathNameSize,
                                    PATHNAME_SIZE_LENGTH,
                                    pDest );

            /**********************************************************/
            /* Copy the pathname across.                              */
            /**********************************************************/
            pSource = DMData.CPInfo.CPList[i].PathName;
            for ( j = 0; j < DMData.CPInfo.CPList[i].PathNameSize; j++ )
                *pDest++ = *pSource++;
        }
    }

    /******************************************************************/
    /* Copy the default metrics path.                                 */
    /******************************************************************/
    TRACE6(TFUNC, "Dflt metrics path", FNULL, 0);
    for ( i = 0; i < pDMSettings->MetricsPathLength;  i++ )
    {
        *pDest++ = DMData.pMetricsPath[i];
    }


    /******************************************************************/
    /* Write the INI file entry for the default font.  The font       */
    /* source is written first; the structure of the rest of the      */
    /* entry depends on the source (engine, resident, code page or    */
    /* card) as follows:                                              */
    /*                                                                */
    /*  Engine font ..... - no further info                           */
    /*                                                                */
    /*  Resident font ... - Index  (of font in resident font index)   */
    /*                                                                */
    /*  Code Page font .. - Index  (of font in resident font index)   */
    /*                    - PosInSource  (of code page in the         */
    /*                          DVTCodePageList - array of length 9)  */
    /*                                                                */
    /*  Cartridge font .. - PosInSource  (of font in its card)        */
    /*                    - CardName  (containing the font - replace  */
    /*                                 '\0's with spaces)             */
    /*                                                                */
    /******************************************************************/
    if ( pDMSettings->DfltFontInfoSize )
    {
        TRACE6(TFUNC, "Dflt font source", FNULL, 0);

        prdm_WriteTextFromWord( DMData.DfltFontInfo.Info.Type,
                                DFLTFONT_SOURCE_LEN,
                                pDest );

        if ( DMData.DfltFontInfo.Info.Type == FT_RESIDENT ||
             DMData.DfltFontInfo.Info.Type == FT_CODE_PAGE )
        {
            TRACE6(TFUNC, "Dflt font index", FNULL, 0);

            prdm_WriteTextFromWord( DMData.DfltFontInfo.Info.Index,
                                    DFLTFONT_INDEX_LEN,
                                    pDest );
        }

        if ( DMData.DfltFontInfo.Info.Type == FT_CODE_PAGE )
        {
            prdm_WriteTextFromWord( DMData.DfltFontInfo.Info.CodePageNo,
                                    DFLTFONT_POS_IN_SRC_LEN,
                                    pDest );
        }

    } /* ... if ( pDMSettings->DfltFontInfoSize ) ................... */

    return;
}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_WriteIniEntry                                     */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   USHORT  PrinterType   Printer type code                          */
/*   HWND     hwnd;        The handle for the dialog window we are in */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function writes the INI entry for the given printer.        */
/*                                                                    */
/**********************************************************************/
/*CON3201
USHORT pascal prdm_WriteIniEntry( PrinterType,
                                  hwnd )

USHORT      PrinterType;
HWND        hwnd;
                 */
USHORT prdm_WriteIniEntry(USHORT      PrinterType,
                          HWND        hwnd)


{
#define TFUNC "prdm_WriteIniEn"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    lpDMIniEntry    pIniEntry;     /* Pointer to INI entry for given  */
                                   /* printer                         */

    /******************************************************************/
    /* Set up local ptr.                                              */
    /******************************************************************/
    pIniEntry = &DMIniEntry[PrinterType];
    if ( DMData.BodyDataChanged )
    {
        /**************************************************************/
        /* Calculate the length of the Source data.  The data is      */
        /* written as follows:                                        */
        /*  - form in paper trays 1 .. MAX_NO_OF_PARER_TRAYS          */
        /*  - form in tractor feed                                    */
        /*  - form in envelope feed                                   */
        /*  - number of manual paper forms                            */
        /*  - manual paper forms                                      */
        /*  - number of manual envelope forms                         */
        /*  - manual envelope forms                                   */
        /* Note that all this data is written whether or not a        */
        /* particular source (e.g. tractor feed, envelope feed ) is   */
        /* available or not.                                          */
        /**************************************************************/
        pDMSettings->SourceDataSize =
                          NO_FORM_CNT_DIGITS *
                               ( MAX_NO_OF_PAPER_TRAYS +
                                 4 +
                                 DMData.ConnsInfo.NoOfManualPaper +
                                 DMData.ConnsInfo.NoOfManualEnv );

        /**************************************************************/
        /* DIAL/NILE :                                                */
        /* Calculate new entry length.                                */
        /**************************************************************/
        pDMSettings->INIEntrySize =
                  HEADER_LENGTH +
                  pDMSettings->NumberOfForms *
                                           (FORM_DATA_LENGTH + 2) +
                  pDMSettings->SourceDataSize +
                  pDMSettings->MetricsPathLength +
                  pDMSettings->NumberOwnedCards * NO_INDEX_DIGITS +
                           MAX_NO_OF_CARD_SLOTS * NO_INDEX_DIGITS +
                  pDMSettings->ShippedCardCount * sizeof(tCard) +
                  pDMSettings->CardDataSize +
                  pDMSettings->DownFontDataSize +
                  pDMSettings->CodePageDataSize +
                  pDMSettings->DfltFontInfoSize;
//                pDMSettings->MachineType;             PD00383

        TRACE6(TFUNC, "New entry size", &pDMSettings->INIEntrySize, 1);

        /**************************************************************/
        /* If the size of the entry is greater than the               */
        /* size of the currently allocated segment we                 */
        /* need to re-allocate memory for the entry.                  */
        /**************************************************************/
        pIniEntry = &DMIniEntry[PrinterType];

        if ( pDMSettings->INIEntrySize > pIniEntry->BufferSize )
        {
            TRACE8(TFUNC, "Realloc of memory", FNULL, 0);

            /**********************************************************/
            /* Free any previous segment allocated.                   */
            /**********************************************************/
            if ( pIniEntry->Data )
/*              SSFREESEG(SELECTOROF( pIniEntry->Data ));            CON3201 */
                SSFREEMEM( pIniEntry->Data );

            /**********************************************************/
            /* Allocate memory for new entry.                         */
            /**********************************************************/
/*          if ( SSALLOCSEG( pDMSettings->INIEntrySize,               CON3201 */
/*                            &SELECTOROF(pIniEntry->Data),           CON3201 */
/*                            0 ) != DOS_OK )                         CON3201 */
            if ( SafeSSALLOCMEM( &pIniEntry->Data,
                                 pDMSettings->INIEntrySize,
                                 0 ) != DOS_OK )
                {
                    return(ERROR_ZERO);
                }
/*          OFFSETOF(pIniEntry->Data) = 0;                           CON3201 */

            pIniEntry->BufferSize = pDMSettings->INIEntrySize;
            pIniEntry->EntrySize  = pDMSettings->INIEntrySize;
        }
        else
        {
            /**********************************************************/
            /* Store the new size of the entry. It is either the same */
            /* or less in this arm.                                   */
            /**********************************************************/
            TRACE4(TFUNC, "Size is smaller", FNULL, 0);
            pIniEntry->EntrySize  = pDMSettings->INIEntrySize;

        }

        /**************************************************************/
        /* Write the body data info to the INI                        */
        /* entry for this printer type.                               */
        /**************************************************************/
        prdm_WriteBodyData( PrinterType );
    }

    /******************************************************************/
    /* Read the current box selections form the main dialog box.      */
    /******************************************************************/
    prdm_QueryMainBoxSelections( hwnd );

    /******************************************************************/
    /* Write the header data info from DMSettings to the              */
    /* INI entry for this printer type                                */
    /******************************************************************/
    /* Changed call from prdm_WriteHeaderData to prde_...   PD00208   */
    /******************************************************************/
    prde_WriteHeaderData( pIniEntry->Data, pDMSettings );

    return(OK);
}
#undef TFUNC




/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_InitMainDlg                                       */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND      hwnd;         Handle of the dialog box                 */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function sets up the dialog box to the current values.      */
/*                                                                    */
/*   PD00183 : Re-used prdm_RadioButtons control for enabling and     */
/*             disabling radio buttons.                               */
/*                                                                    */
/**********************************************************************/
void prdm_InitMainDlg(HWND hwnd )

{
#define TFUNC "prdm_InitMain"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT         PrinterType;      /* Type of the current printer   */
    USHORT         i;                /* Loop variable                 */
    MRESULT        DlgResult;        /* Result of a call to Win.. fn  */
    PBYTE          pDest, pSource;   /* Working pointers              */
    RadCtrlType    Source;           /* Radio button control struc    */
    lpDDTType      pDDT;             /* DDT pointer for this printer  */
    BOOL           DuplexGreyed;
    USHORT         WndId;            /* ID for selecting items in the */
                                     /* dialog box                    */
    SHORT          j;                /*                               */
    USHORT         CheckBoxValue;    /* PD00769                       */

    BOOL           WinResult;        /* CON3201 some of the Win fns   */
                                     /* return BOOL                   */

    /******************************************************************/
    /* Turn off 'Close' and 'Task Manager' options on the system      */
    /* menu.                                                          */
    /******************************************************************/
//  prdm_RemoveMenuOptions( hwnd );

    /******************************************************************/
    /* Get the current printer type.                                  */
    /******************************************************************/
    PrinterType = pDMSettings->PrinterType;
    pDDT = DDT[PrinterType];

    /******************************************************************/
    /* Build the window title - this consists of:                     */
    /*  - the printer type .. eg. ProPrinter II                       */
    /*  - the printer name .. eg. "PRINTER1"  (in brackets)           */
    /******************************************************************/
    /* Add "Printer Properties: " to front of string          PD00690 */
    /******************************************************************/
    WinLoadString( hab,
                   DMData.HModule,
                   IDS_PP_SETUP_CAPTION,
                   SLEN_BOX_MESSAGE,
                   (PSZ)szMessage );

    for ( pDest = szMessage;  *pDest != '\0'; )
          pDest++;

    WinLoadString( hab,
                   DMData.HModule,
                   IDS_FIRST_PRINTER + PrinterType,
                   SLEN_BOX_MESSAGE,
                   (PSZ)pDest );                           /* PD00690 */

    while ( *pDest != '\0' )                               /* PD00690 */
          pDest++;

    /******************************************************************/
    /* Add in the printer name surrounded by brackets - we know that  */
    /* this is not null since we would have returned with an error    */
    /* earlier.                                                       */
    /******************************************************************/
    *pDest++ = ' ';
    *pDest++ = '(';
    *pDest++ = ' ';

    pSource = DMData.PrinterName;

    while ( *pSource != '\0' )
       *pDest++ = *pSource++;

    *pDest++ = ' ';
    *pDest++ = ')';
    *pDest   = '\0';

    /******************************************************************/
    /* Update Window title                                            */
    /******************************************************************/
    (void)WinSetWindowText( hwnd, szMessage );

    /******************************************************************/
    /* Load the caption to be used for all message boxes.             */
    /* PS Tidy up. Remove this, just to string copy of szMessage>Not  */
    /* even used.                                                     */
    /******************************************************************/
    WinLoadString( hab,
                   DMData.HModule,
                   IDS_FIRST_PRINTER + PrinterType,
                   40,
                   (PSZ)szCaption );

    /**************************************************************************/
    /*  600x600 : put in some error checking                                  */
    /**************************************************************************/
    if ( pDMSettings->Resolution >= pDDT->DDTNoOfRasterModes )
        pDMSettings->Resolution = pDDT->DDTNoOfRasterModes-1;

    /***********************************************************************/
    /* Fill in the list of supported resolutions if a list box is          */
    /* used.                                                               */
    /*                                                                     */
    /*  600X600: write out the resolutions with highest value 1st.         */
    /*  Make sure that the list box is there by checking for radio buttons */
    /***********************************************************************/
    if ( !(pDDT->DDTDialogFlags & DDT_RADIO_RESOLUTION) &&
         (WinWindowFromID (hwnd, DB_RAD_PPRES0) == 0) )
    {
        for ( i = 0; i < pDDT->DDTNoOfRasterModes; i++ )
        {
            DlgResult = WinSendDlgItemMsg(
                          hwnd,
                          DB_LST_PPRESOLUTION,
                          LM_INSERTITEM,
                          (MPARAM)(ULONG)LIT_END,
                          MPFROMP(pDDT->DDTRasterMode[i].Description) );
        }

        DlgResult = WinSendDlgItemMsg(
                        hwnd,
                        DB_LST_PPRESOLUTION,
                        LM_SELECTITEM,
                        (MPARAM)(ULONG)pDMSettings->Resolution,
                        (MPARAM)(ULONG)TRUE );
    }

    /******************************************************************/
    /* Select the current resolution using radio buttons.             */
    /******************************************************************/
    if ( ( pDDT->DDTDialogFlags & DDT_RADIO_RESOLUTION ) ||
         (WinWindowFromID (hwnd, DB_RAD_PPRES0) != 0) )
    {
        Source.RadNumber    = 4;
        Source.RadItem[0]   = DB_RAD_PPRES0;
        Source.RadItem[1]   = DB_RAD_PPRES1;
        Source.RadItem[2]   = DB_RAD_PPRES2;
        Source.RadItem[3]   = DB_RAD_PPRES3;
        Source.RadGreyed    = FALSE;
        Source.RadHighlight = pDMSettings->Resolution;

        (VOID) prdm_RadioButtonControl (hwnd, &Source);
    }

    /******************************************************************/
    /* Fill in the list of defined forms                              */
    /******************************************************************/
    prdm_InitFormList( hwnd, DB_LST_DEFINED_FORMS );

    /******************************************************************/
    /* Select the "current" form in the listbox.                      */
    /******************************************************************/
    DlgResult = WinSendDlgItemMsg(
                        hwnd,
                        DB_LST_DEFINED_FORMS,
                        LM_SELECTITEM,
                        (MPARAM)(ULONG)pDMSettings->SelectedForm,
                        (MPARAM)(ULONG)TRUE );

    /******************************************************************/
    /* Select the current paper orientation                           */
    /******************************************************************/
    Source.RadNumber    = 2;
    Source.RadItem[0]   = DB_RAD_PPPORTRAIT;
    Source.RadItem[1]   = DB_RAD_PPLANDSCAPE;
    Source.RadGreyed    = FALSE;
    Source.RadHighlight = pDMSettings->Orientation;

    (VOID) prdm_RadioButtonControl (hwnd, &Source);

    /******************************************************************/
    /* DIAL/NILE :                                                    */
    /* Select the machine version for Nile and Tibers only.           */
    /*                                                                */
    /* PD00295 : Changed the flags a bit to make tests less printer   */
    /* specific and fix a bug.                                        */
    /******************************************************************/
    if (pDDT->DDTDialogFlags & DDT_NLS_VERSION)
    {
        Source.RadNumber  = 2;
        Source.RadItem[0] = DB_RAD_NLS_MACHINE;
        Source.RadItem[1] = DB_RAD_US_MACHINE;

        if (pDDT->DDTFontFlags & DDT_NLS_FONTS_OPTIONAL )
        {
            /**********************************************************/
            /* The value stored in the INI file for machine type is   */
            /* 1 and 2. So subtract one to get it into the range of   */
            /* indices in the radio button structure.                 */
            /**********************************************************/
            Source.RadGreyed    = FALSE;
            Source.RadHighlight = pDMSettings->MachineType - 1;
        }
        else
        {
            /**********************************************************/
            /* This function is not supported on the 4226, so grey it */
            /* and highlight nothing.                                 */
            /**********************************************************/
            Source.RadGreyed    = TRUE;
            Source.RadHighlight = Source.RadNumber + 1;
        }

        /**************************************************************/
        /* Now select the buttons.                                    */
        /**************************************************************/
        (VOID) prdm_RadioButtonControl (hwnd, &Source);
    }

    /******************************************************************/
    /* Set FormFeed control button                                    */
    /******************************************************************/
    if ( DDT[pDMSettings->PrinterType]->DDTFormFlags & DDT_VAR_FORM_FEED_CONTROL )
    {
        Source.RadNumber    = 3;
        Source.RadItem[0]   = DB_RAD_FF_NONE;
        Source.RadItem[1]   = DB_RAD_FF_COMPULSORY;
        Source.RadItem[2]   = DB_RAD_FF_CONDITIONAL;
        Source.RadGreyed    = FALSE;
        Source.RadHighlight = pDMSettings->FFSet;

        (VOID) prdm_RadioButtonControl (hwnd, &Source);
    }

    /******************************************************************/
    /* Select the printer fonts available flag by: switching off the  */
    /*       mode and switching on the correct mode                   */
    /*                                                                */
    /* PD00604 : We now have three buttons for the Nile/Tiber/Dakotas */
    /* and only 2 on the other Pro's & Q's.                           */
    /******************************************************************/
    if (pDDT->DDTDialogFlags & DDT_LIMIT_FONTS)
    {
        Source.RadNumber    = 3;
        Source.RadItem[0]   = DB_RAD_FONTS_LIMITED;
        Source.RadItem[1]   = DB_RAD_FONTS_OFF;
        Source.RadItem[2]   = DB_RAD_FONTS_ON_2;
        Source.RadGreyed    = FALSE;
        Source.RadHighlight = pDMSettings->PelAddrFontType;

        (VOID) prdm_RadioButtonControl (hwnd, &Source);
    }
    else
    {
        Source.RadNumber    = 2;
        Source.RadItem[0]   = DB_RAD_FONTS_ON;
        Source.RadItem[1]   = DB_RAD_FONTS_OFF;
        Source.RadGreyed    = FALSE;
        Source.RadHighlight = pDMSettings->PelAddrFontType;

        (VOID) prdm_RadioButtonControl (hwnd, &Source);
    }

    /******************************************************************/
    /* Display the options for default spool files (ie IBM_Q_STD or   */
    /* IBM_Q_RAW) if the box is being drawn for the first time.       */
    /******************************************************************/
    DlgResult = WinSendDlgItemMsg(
                             hwnd,
                             DB_LST_SPOOL_FILE,
                             LM_INSERTITEM,
                             (MPARAM)(ULONG)LIT_END,
                             (MPARAM)(UCHAR  *)szIBMQSTD );

    DlgResult = WinSendDlgItemMsg(
                             hwnd,
                             DB_LST_SPOOL_FILE,
                             LM_INSERTITEM,
                             (MPARAM)(ULONG)LIT_END,
                             (MPARAM)(UCHAR  *)szIBMQRAW );

    /******************************************************************/
    /* Select the current spool file type.                            */
    /******************************************************************/
    DlgResult = WinSendDlgItemMsg(
                             hwnd,
                             DB_LST_SPOOL_FILE,
                             LM_SELECTITEM,
                             (MPARAM)(ULONG)pDMSettings->DefaultSpoolIndex,
                             (MPARAM)(ULONG)TRUE );

    /******************************************************************/
    /* Process the variable source radio buttons if they are          */
    /* supported on the printer.                                      */
    /*                                                                */
    /* PD00183 : Re-designed the way that the sources are displayed   */
    /* so that all the work is done in the InitSourceBoxes function.  */
    /******************************************************************/
    if ( pDDT->DDTSourceFlags & DDT_VAR_PAPER_SOURCE_SUPPORT )
    {
        /**************************************************************/
        /* Initilise the source.                                      */
        /**************************************************************/
        prdm_InitSourceBoxes( hwnd );
    }

    /******************************************************************/
    /* Check if Code Pages are supported on this printer.             */
    /******************************************************************/
    if ( pDDT->DDTFontFlags & DDT_ADD_CODE_PAGE_SUPPORT )
    {

        Source.RadNumber  = 2;
        Source.RadItem[0] = DB_RAD_CPMEM_NO;
        Source.RadItem[1] = DB_RAD_CPMEM_YES;

        if ( pDDT->DDTFontFlags & DDT_CODE_PAGE_NOTOPTION )
        {
            /**********************************************************/
            /* If this option is not supported then grey it and leave */
            /* it with memory enabled                                 */
            /**********************************************************/
            Source.RadGreyed    = TRUE;
            Source.RadHighlight = 1;
        }
        else
        {
            /**********************************************************/
            /* If it is supported then enable it with the correct     */
            /* item highlighted.                                      */
            /**********************************************************/
            Source.RadGreyed    = FALSE;
            Source.RadHighlight = pDMSettings->DownCPMemAvail;
        }

        /**************************************************************/
        /* Now select them,                                           */
        /**************************************************************/
        (VOID) prdm_RadioButtonControl (hwnd, &Source);
    }
    /* ............ if ( DDT_ADD_CODE_PAGE_SUPPORT ) ................ */

    /******************************************************************/
    /* Duplex options:                                                */
    /*                                                                */
    /* DDT_DUPLEX_SUPPORT: Printer has the duplex control radio       */
    /* buttons in the main dialog.                                    */
    /*                                                                */
    /* DDT_DUPLEX_OPTIONAL: Printer has the duplex option radio       */
    /* buttons on the dialog. The value of this dictates whether the  */
    /* duplex control is greyed or not.                               */
    /*                                                                */
    /* DDT_DUPLEX_NOTSUPPORT: Overrides the DDT_DUPLEX_OPTIONAL flag  */
    /* to grey out the duplex control all the time.                   */
    /******************************************************************/

    if ( pDDT->DDTSourceFlags & DDT_DUPLEX_SUPPORT )
    {
        /**************************************************************/
        /* Assume that the duplex control is to be displayed          */
        /**************************************************************/
        DuplexGreyed = FALSE;

        if ( pDDT->DDTSourceFlags & DDT_DUPLEX_OPTIONAL )
        {
            /**********************************************************/
            /* First the option to enable and disable it.             */
            /**********************************************************/
            Source.RadNumber    = 2;
            Source.RadItem[0]   = DB_RAD_DUP_DISABLED;
            Source.RadItem[1]   = DB_RAD_DUP_ENABLED;
            Source.RadGreyed    = FALSE;
            Source.RadHighlight = pDMSettings->DuplexEnabled;

            (VOID) prdm_RadioButtonControl (hwnd, &Source);

            DuplexGreyed = !pDMSettings->DuplexEnabled;
        }

        /**************************************************************/
        /* Now the type of duplex option.                             */
        /**************************************************************/
        Source.RadNumber  = 3;
        Source.RadItem[0] = DB_RAD_SIMPLEX;
        Source.RadItem[1] = DB_RAD_NORMAL;
        Source.RadItem[2] = DB_RAD_TUMBLE;

        if (DuplexGreyed || pDDT->DDTSourceFlags & DDT_DUPLEX_NOTSUPPORT)
        {
            /**********************************************************/
            /* If duplex is disabled then grey the box and have       */
            /* nothing highlighted.                                   */
            /**********************************************************/
            Source.RadGreyed    = TRUE;
            Source.RadHighlight = Source.RadNumber + 1;
        }
        else
        {
            /**********************************************************/
            /* If duplex is enabled then take the value from the INI  */
            /**********************************************************/
            Source.RadGreyed    = FALSE;
            Source.RadHighlight = pDMSettings->SimDup;
        }

        /**************************************************************/
        /* Now select the radio buttons.                              */
        /**************************************************************/
        (VOID) prdm_RadioButtonControl (hwnd, &Source);
    }

    /******************************************************************/
    /* Set the active window                                          */
    /* PD00263 : Remove set active window. Now window always remains  */
    /* in the same place.                                             */
    /******************************************************************/
//  WinSendMsg( DMData.hwndHelp,
//              HM_SET_ACTIVE_WINDOW,
//              hwnd,
//              hwnd );

    /******************************************************************/
    /* Reset the cursor shape to its original shape.                  */
    /******************************************************************/
    (void) WinSetPointer( HWND_DESKTOP,
                          (HPOINTER)DMData.CursorHandle );

    /******************************************************************/
    /* Set the focus to the ENTER button if this is the first time    */
    /* the box is drawn; otherwise it will be left in the printer     */
    /* list box.                                                      */
    /******************************************************************/
    WinResult = WinSetFocus( HWND_DESKTOP,
                             WinWindowFromID(hwnd,DB_PSH_PPENTER) );

}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_ReadBodyData                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   USHORT    PrinterType   Printer type code                        */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function reads the variable length body data from           */
/*   the INI entry for the given printer to DMData.                   */
/*                                                                    */
/**********************************************************************/
USHORT prdm_ReadBodyData(USHORT PrinterType )


{
#define TFUNC "prdm_ReadBody"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    PBYTE      pSource, pDest; /* Working pointers                    */
    SHORT      FormNum;        /* Loop control to fetch data on all   */
                               /* the defined forms                   */
    USHORT     Result;         /* Function call return values         */
    USHORT     i, j;           /* Loop control variables              */
    psForm     Form;           /* Pointer to sForm structure for      */
    psForm     NewForm;        /* constructing a linked list of these */
    USHORT     ListIndex;      /* Index of selected item in list box  */
    PUSHORT    CardBuffer;     /* For indexes of owned cards          */
    PBYTE      pCardData;      /* Pointer to added card data          */
    lpCard     pShipData;      /* Pointer to shipped card data        */
    USHORT     CodePageNo;     /* Index into DVT code page list       */
    USHORT     PathNameSize;   /* For download fonts and code pages   */
    PUSHORT    FormBuffer;     /* For indexes of manual forms         */
    USHORT     Work;           /* Used to read and write the download */
                               /* file size in two parts              */
    USHORT    NoOfResidentFonts;                  /* PD00651, PD00657 */

    /******************************************************************/
    /* Set the working pointer to the address of the variable length  */
    /* data in the INI entry for the given printer.                   */
    /******************************************************************/
    pSource = DMIniEntry[PrinterType].Data + HEADER_LENGTH;
    TRACE6(TFUNC, "Start of Form data", pSource, 8);

    /******************************************************************/
    /* For every form that is defined: Call SSALLOCSEG to get         */
    /* storage space for the data, set up a pointer to it either      */
    /* in DMData or in the NextForm field of the previous form        */
    /* definition and copy the data from the OS2.INI file.            */
    /******************************************************************/
    for ( FormNum = 0; FormNum < pDMSettings->NumberOfForms; FormNum++ )
    {
        /**************************************************************/
        /* Set NewForm to NULL here as SSALLOCSEG returns as a        */
        /* selector only and the offset must be zero.                 */
        /**************************************************************/
/*      Result = SSALLOCSEG (sizeof(sForm), &SELECTOROF(NewForm), 0); CON3201 */
        Result = SafeSSALLOCMEM (&NewForm, sizeof(sForm), 0);

        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCSEG Fail", &Result, 1, Result);
            return ((USHORT)ERROR_ZERO);
        }

/*      OFFSETOF(NewForm) = 0;                                        CON3201 */

        if (!FormNum)
            DMData.Forms = NewForm;
        else
            Form->NextForm = NewForm;

        /**************************************************************/
        /* Advance Form to the last link in the current chain.        */
        /**************************************************************/
        Form = NewForm;
        Form->NextForm = FNULL;

        /**************************************************************/
        /* Read in the form type and form ID                          */
        /**************************************************************/
        Form->FormType = *pSource++;
        Form->FormID   = *pSource++;

        /**************************************************************/
        /* Copy form data into our storage converting ALT_POINTs      */
        /* to the correct decimal point character.                    */
        /**************************************************************/
        for ( i = 0; i < FORM_DATA_LENGTH; i++, pSource++ )
        {
            Form->FormData[i] = (*pSource == ALT_POINT)
                                     ? DMData.DecimalPoint : *pSource;
        }
    }
    /*.. for (FormNum = 0; FormNum < ....every defined form.......*/

    /******************************************************************/
    /* Set NumberOfForms to the number of forms we have succeeded     */
    /* in fetching from OS2.INI.                                      */
    /******************************************************************/
    pDMSettings->NumberOfForms = FormNum;

    /******************************************************************/
    /* Get the source form data.                                      */
    /* The source form data has the following format :-               */
    /* Form number in paper trays 1 .. MAX_NO_OF_PAPER_TRAYS          */
    /* Form number in the tractor feed                                */
    /* Form number in the envelope tray                               */
    /* Number of manual paper forms followed by form numbers          */
    /* Number of manual envelope forms followed by form numbers       */
    /******************************************************************/
    if ( pDMSettings->SourceDataSize )
    {
        /**************************************************************/
        /* Get the form numbers mounted in the automatic paper trays. */
        /**************************************************************/
        for ( i = 0; i < NO_OF_AUTO_TRAYS; i++ )
        {
            prdm_ReadWordFromText( DMData.ConnsInfo.AutoTrayForm[i],
                                   NO_FORM_CNT_DIGITS,
                                   pSource );
        }

        /**************************************************************/
        /* Get the number of manual paper forms.                      */
        /**************************************************************/
        prdm_ReadWordFromText( DMData.ConnsInfo.NoOfManualPaper,
                               NO_FORM_CNT_DIGITS,
                               pSource );

        /**************************************************************/
        /* Allocate memory to hold the manual form numbers.           */
        /**************************************************************/
/*      Result = SSALLOCSEG ( (2 * DMData.ConnsInfo.NoOfManualPaper), CON3201 */
/*                            &SELECTOROF(FormBuffer),                CON3201 */
/*                            0 );                                    CON3201 */
        Result = SafeSSALLOCMEM (&FormBuffer,
                                (2 * DMData.ConnsInfo.NoOfManualPaper),
                                 0 );
        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
            return ((USHORT)ERROR_ZERO);
        }

/*      OFFSETOF(FormBuffer) = 0;                                     CON3201 */

        /**************************************************************/
        /* Now read in form numbers for the manual paper forms.       */
        /**************************************************************/
        for ( i = 0; i < DMData.ConnsInfo.NoOfManualPaper; i++ )
        {
            prdm_ReadWordFromText( ListIndex,
                                   NO_FORM_CNT_DIGITS,
                                   pSource );

            FormBuffer[i] = ListIndex;
        }

        DMData.ConnsInfo.pManualPaper = FormBuffer;

        /**************************************************************/
        /* Get the number of manual envelope forms.                   */
        /**************************************************************/
        prdm_ReadWordFromText( DMData.ConnsInfo.NoOfManualEnv,
                               NO_FORM_CNT_DIGITS,
                               pSource );

        /**************************************************************/
        /* Allocate memory to hold manual envelope form numbers.      */
        /**************************************************************/
/*      Result = SSALLOCSEG ( (2 * DMData.ConnsInfo.NoOfManualEnv),   CON3201 */
/*                            &SELECTOROF(FormBuffer),                CON3201 */
/*                            0 );                                    CON3201 */
        Result = SafeSSALLOCMEM (&FormBuffer,
                                (2 * DMData.ConnsInfo.NoOfManualEnv),
                                 0 );
        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
            return ((USHORT)ERROR_ZERO);
        }

/*      OFFSETOF(FormBuffer) = 0;                                    CON3201 */

        /**************************************************************/
        /* Now read in form numbers for the manual paper forms.       */
        /**************************************************************/
        for ( i = 0; i < DMData.ConnsInfo.NoOfManualEnv; i++ )
        {
            prdm_ReadWordFromText( ListIndex,
                                   NO_FORM_CNT_DIGITS,
                                   pSource );

            FormBuffer[i] = ListIndex;
        }

        DMData.ConnsInfo.pManualEnvelope = FormBuffer;

    }  /*..........if pDMSettings->SourceDataSize != 0 ...........*/
    else
    {
        /**************************************************************/
        /* If no source data set the numbers to zero.                 */
        /**************************************************************/
        DMData.ConnsInfo.NoOfManualPaper = 0;
        DMData.ConnsInfo.NoOfManualEnv   = 0;
    }

    /******************************************************************/
    /* Get all the indexes of the owned cards.                        */
    /******************************************************************/
    if ( pDMSettings->NumberOwnedCards )
    {
        /**************************************************************/
        /* Allocate memory for the card index list.                   */
        /**************************************************************/
/*      Result = SSALLOCSEG ( pDMSettings->NumberOwnedCards * 2,     CON3201 */
/*                            &SELECTOROF(CardBuffer),               CON3201 */
/*                            0 );                                   CON3201 */
        Result = SafeSSALLOCMEM ( &CardBuffer,
                                  (pDMSettings->NumberOwnedCards * 2),
                                  0 );
        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
            return ((USHORT)ERROR_ZERO);
        }

/*      OFFSETOF(CardBuffer) = 0;                                    CON3201 */

        /**************************************************************/
        /* For each index in the Ini file convert from text and       */
        /* to list in memory                                          */
        /**************************************************************/
        for ( i = 0; i < pDMSettings->NumberOwnedCards; i++ )
        {
            prdm_ReadWordFromText( ListIndex,
                                   NO_INDEX_DIGITS,
                                   pSource );

            CardBuffer[i] = ListIndex;
        }

        /**************************************************************/
        /* Attach list to the global data structure                   */
        /**************************************************************/
        DMData.OwnedIndexList   = CardBuffer;
        DMData.FreeOwnedEntries = 0;
    }

    /******************************************************************/
    /* Get the index of the cards in the slots.                       */
    /******************************************************************/
    for ( i = 0; i < MAX_NO_OF_CARD_SLOTS; i++ )
    {
        prdm_ReadWordFromText( DMData.Slot[i].Index,
                               NO_INDEX_DIGITS,
                               pSource );

        DMData.Slot[i].Index--;
    }

    /******************************************************************/
    /* Get the names of all the cards from the shipped set.           */
    /******************************************************************/
    if ( pDMSettings->ShippedCardCount )
    {
        /**************************************************************/
        /* Allocate memory for the shipped card information.          */
        /**************************************************************/
/*      Result = SSALLOCSEG ( (pDMSettings->ShippedCardCount *       CON3201 */
/*                                                 sizeof(tCard)),   CON3201 */
/*                            &SELECTOROF(pShipData),                CON3201 */
/*                             0 );                                  CON3201 */
        Result = SafeSSALLOCMEM ( &pShipData,
                        (pDMSettings->ShippedCardCount * sizeof(tCard)),
                                  0 );
        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
            return ((USHORT)ERROR_ZERO);
        }

/*      OFFSETOF(pShipData) = 0;                                     CON3201 */

        /**************************************************************/
        /* Copy the data from the Ini file buffer converting          */
        /* spaces to null values.                                     */
        /**************************************************************/
        for ( i = 0;
              i < (pDMSettings->ShippedCardCount * sizeof(tCard));
              i++, pSource++ )
        {
            ((PBYTE)pShipData)[i] =
                          (*pSource == ' ') ? (BYTE)'\0' : *pSource;
        }

        DMData.pShippedCards = pShipData;
    }

    /******************************************************************/
    /* Get the path names of all the added cards.                     */
    /******************************************************************/
    if ( pDMSettings->CardDataSize )
    {
        /**************************************************************/
        /* Allocate memory for the card information.                  */
        /**************************************************************/
/*      Result = SSALLOCSEG ( pDMSettings->CardDataSize,            CON3201 */
/*                            &SELECTOROF(pCardData),               CON3201 */
/*                            0 );                                  CON3201 */
        Result = SafeSSALLOCMEM ( &pCardData,
                                  pDMSettings->CardDataSize,
                                  0 );

        if ( Result != DOS_OK )
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
            return ((USHORT)ERROR_ZERO);
        }

/*      OFFSETOF(pCardData) = 0;                                     CON3201 */

        /**************************************************************/
        /* Copy the data from the Ini file buffer converting          */
        /* spaces to null values.                                     */
        /**************************************************************/
        for ( i = 0; i < pDMSettings->CardDataSize; i++, pSource++ )
            pCardData[i] = (*pSource == ' ') ? (BYTE)'\0' : *pSource;

        DMData.pCardData = pCardData;
    }

    /******************************************************************/
    /* Get the info for the download fonts.                           */
    /******************************************************************/
    if ( pDMSettings->NumberOfDownFonts )
    {
        /**************************************************************/
        /* Allocate memory for the download font list.                */
        /**************************************************************/
/*      Result = SSALLOCSEG ( (pDMSettings->NumberOfDownFonts *      CON3201 */
/*                                   sizeof(DownloadStrucType)),     CON3201 */
/*                             &SELECTOROF(DMData.pDownFontList),    CON3201 */
/*                             0 );                                  CON3201 */
        Result = SafeSSALLOCMEM ( &DMData.pDownFontList,
                                  (pDMSettings->NumberOfDownFonts *
                                  sizeof(DownloadStrucType)),
                                  0 );

        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
            return (ERROR_ZERO);
        }

/*      OFFSETOF(DMData.pDownFontList) = 0;                          CON3201 */

        /**************************************************************/
        /* Cycle through the fonts in the INI file.                   */
        /**************************************************************/
        for ( i = 0; i < pDMSettings->NumberOfDownFonts; i++ )
        {
            /**********************************************************/
            /* Get the size of the pathname so we know how much       */
            /* memory to allocate for the info for each font          */
            /* (pSource is not incremented here).                     */
            /**********************************************************/
            PathNameSize = 0;
            for ( j = 0; j < PATHNAME_SIZE_LENGTH; j++ )
            {
                PathNameSize *= 10;
                PathNameSize += pSource[j] - '0';
            }

            /**********************************************************/
            /* Allocate the memory for this font and set the          */
            /* pointer in the font list.                              */
            /**********************************************************/
/*          Result = SSALLOCSEG ( PathNameSize + DM_DOWN_FXD_LENGTH, CON3201 */
/*                                 &SELECTOROF(pDest),               CON3201 */
/*                                 0 );                              CON3201 */

            Result = SafeSSALLOCMEM ( &pDest,
                                  (PathNameSize + DM_DOWN_FXD_LENGTH),
                                   0 );
            if (Result != DOS_OK)
            {
                Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
                return ((USHORT)ERROR_ZERO);
            }

/*          OFFSETOF(pDest) = 0;                                     CON3201 */

            DMData.pDownFontList[i].DownloadInfo = pDest;

            /**********************************************************/
            /* Copy across the download info (except the type and     */
            /* the download font file size)                           */
            /* i.e. pathname size, path, space, name, space,          */
            /* typeface, codepage, pointsize.                         */
            /**********************************************************/
            for ( j = 0; j < PathNameSize + DM_DOWN_FXD_LENGTH; j++ )
                *pDest++ = *pSource++;

            /**********************************************************/
            /* Get the download type (initial or dynamic).            */
            /**********************************************************/
            DMData.pDownFontList[i].DownloadType = *pSource++;

            /**********************************************************/
            /* Get the download font file size.                       */
            /* The size could be > 64K so we have to use a dword.     */
            /* The hiword was written as three text digits; then      */
            /* the low word as five.                                  */
            /**********************************************************/
            prdm_ReadWordFromText( Work,
                                   DOWNFILE_SIZE_HI_LEN,
                                   pSource );

            (((PUSHORT)
                &(DMData.pDownFontList[i].DownloadSize))[1]) = Work;

            prdm_ReadWordFromText( Work,
                                   DOWNFILE_SIZE_LO_LEN,
                                   pSource );

            (((PUSHORT)
                &(DMData.pDownFontList[i].DownloadSize))[0]) = Work;
        }

    }   /* end of get download font info                              */


    /******************************************************************/
    /* Get the info for the downloadable code pages.                  */
    /******************************************************************/
    for ( i = 0; i < pDMSettings->NoOfAddedCPs; i++ )
    {
        /**************************************************************/
        /* Read the code page index and the pathname size.  The index */
        /* is into the DVTCodePageCaps array; entries are only held   */
        /* in DMData for the added code pages.                        */
        /**************************************************************/
        prdm_ReadWordFromText( CodePageNo,
                               NO_CODE_PAGE_DIGITS,
                               pSource );

        prdm_ReadWordFromText( PathNameSize,
                               PATHNAME_SIZE_LENGTH,
                               pSource );

        DMData.CPInfo.CPList[i].Added = CodePageNo;

        DMData.CPInfo.CPList[CodePageNo - 2].PathNameSize = PathNameSize;

        /**************************************************************/
        /* Allocate memory for the code page path.  It is stored in   */
        /* DMData without a terminator.                               */
        /**************************************************************/
/*      Result = SSALLOCSEG(                                         CON3201 */
/*                     PathNameSize,                                 CON3201 */
/*                     &SELECTOROF(DMData.CPInfo.                    CON3201 */
/*                                CPList[CodePageNo - 2].PathName),  CON3201 */
/*                     0 );                                          CON3201 */
        Result = SafeSSALLOCMEM( &(DMData.CPInfo.
                                   CPList[CodePageNo - 2].PathName),
                                 PathNameSize,
                                 0 );

        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
            return (ERROR_ZERO);
        }

/*      OFFSETOF(DMData.CPInfo.CPList[CodePageNo - 2].PathName) = 0; CON3201 */

        /**************************************************************/
        /* Copy the pathname across.                                  */
        /**************************************************************/
        pDest = DMData.CPInfo.CPList[CodePageNo - 2].PathName;
        for ( j = 0; j < PathNameSize; j++ )
            *pDest++ = *pSource++;

    }

    /******************************************************************/
    /* Get the default metrics path.                                  */
    /******************************************************************/
    if ( pDMSettings->MetricsPathLength )
    {
        TRACE6(TFUNC, "Get dflt metrcs path", FNULL, 0);

        /**************************************************************/
        /* Allocate memory for the metrics path.  It is stored in     */
        /* the INI file without a null terminator so add one to       */
        /* the end when we put it in DMData.                          */
        /**************************************************************/
/*      Result = SSALLOCSEG( (pDMSettings->MetricsPathLength + 1),   CON3201 */
/*                            &SELECTOROF(DMData.pMetricsPath),      CON3201 */
/*                            0 );                                   CON3201 */

        Result = SafeSSALLOCMEM( &DMData.pMetricsPath,
                             (pDMSettings->MetricsPathLength + 1),
                              0 );

        if (Result != DOS_OK)
        {
            Ring3LOGDOSERR(TFUNC, "SSALLOCMEM Fail", &Result, 1, Result);
            return ((USHORT)ERROR_ZERO);
        }

/*      OFFSETOF(DMData.pMetricsPath) = 0;                            CON3201 */

        /**************************************************************/
        /* Copy the data from the Ini file buffer and add a '\0'.     */
        /**************************************************************/
        for ( i = 0; i < pDMSettings->MetricsPathLength; i++ )
            DMData.pMetricsPath[i] = *pSource++;

        DMData.pMetricsPath[i] = '\0';
    }

    /******************************************************************/
    /* Get the default font info - see prdm_WriteBodyData for details */
    /* of the structure of the INI entry.                             */
    /******************************************************************/
    if ( pDMSettings->DfltFontInfoSize )
    {
        DMData.DfltFontInfo.Info.Type = *pSource++ - '0';

        if ( DMData.DfltFontInfo.Info.Type == FT_RESIDENT ||
             DMData.DfltFontInfo.Info.Type == FT_CODE_PAGE )
        {
            /**********************************************************/
            /* Read in the index of the font in the resident font     */
            /* list.                                                  */
            /**********************************************************/
            prdm_ReadWordFromText( DMData.DfltFontInfo.Info.Index,
                                   DFLTFONT_INDEX_LEN,
                                   pSource );

            /******************************************************************/
            /*  PD00657 : Add range checking on the font index for Nile/Tiber.*/
            /******************************************************************/
            if (DDT[PrinterType]->DDTDriverType == DDT_IBM42XX_DRV)
            {
               if ( (PrinterType == IBM_NILE_9) ||
                    (PrinterType == IBM_TIBER_9) )
               {
                   if (pDMSettings->MachineType == NLS_MACHINE)
                       NoOfResidentFonts = NLS_9WIRE;
                   else
                       NoOfResidentFonts = US_9WIRE;
               }
               else /* its a 24-wire */
               {
                   if (pDMSettings->MachineType == NLS_MACHINE)
                       NoOfResidentFonts = NLS_24WIRE;
                   else
                       NoOfResidentFonts = US_24WIRE;
               }

               if ((PrinterType >= IBM_NILE_9) && (PrinterType <= IBM_TIBER_24))
               {
                  if ( DMData.DfltFontInfo.Info.Index > NoOfResidentFonts)
                  {
                    DMData.DfltFontInfo.Info.Index = 0;
                  }
               }
            }
        }

        if ( DMData.DfltFontInfo.Info.Type == FT_CODE_PAGE )
        {
            /**********************************************************/
            /* Read in the position of the codepage in the            */
            /* DVTCodePageList.                                       */
            /**********************************************************/
            prdm_ReadWordFromText( DMData.DfltFontInfo.Info.CodePageNo,
                                   DFLTFONT_POS_IN_SRC_LEN,
                                   pSource );
        }

    }
    /*  ... if ( pDMSettings->DfltFontInfoSize ) ...................  */

    TRACE4(TFUNC, "Exit OK", FNULL, 0);
    return(OK);
}
#undef TFUNC



/*CON3201

USHORT pascal prdm_DispMessageBox ( hwnd,
                                    MessageID,
                                    MessageLength,
                                    WindowID,
                                    MessageStyle )
HWND         hwnd;
USHORT       MessageID;
SHORT        MessageLength;
USHORT       WindowID;
USHORT       MessageStyle;
                          */
USHORT  prdm_DispMessageBox (HWND         hwnd,
                             USHORT       MessageID,
                             SHORT        MessageLength,
                             USHORT       WindowID,
                             USHORT       MessageStyle)

{
    /******************************************************************/
    /* Load the message string from resources.                        */
    /******************************************************************/
    WinLoadString( hab,
                   DMData.HModule,
                   MessageID,
                   MessageLength,
                   (PSZ)szMessage );

    /******************************************************************/
    /* Put up the box and return the response.                        */
    /******************************************************************/
    return( WinMessageBox( HWND_DESKTOP,
                           hwnd,
                           (PSZ)szMessage,
                           (PSZ)szCaption,
                           WindowID,
                           MessageStyle) );
}

/* CON3201
USHORT pascal prdm_DispConversionMsg ( hwnd,
                                    MessageID,
                                    MessageLength,
                                    WindowID,
                                    MessageStyle )
HWND         hwnd;
USHORT       MessageID;
SHORT        MessageLength;
USHORT       WindowID;
USHORT       MessageStyle;
                                  */

USHORT prdm_DispConversionMsg (HWND         hwnd,
                               USHORT       MessageID,
                               SHORT        MessageLength,
                               USHORT       WindowID,
                               USHORT       MessageStyle)

{
CHAR                szCaptionMsg[40];

    /******************************************************************/
    /* Load the driver name string from resources. PD00368            */
    /******************************************************************/
    WinLoadString( hab,
                   prdd_ModHandle,
                   IDS_SMB_CAPTION,
                   40,
                   (PSZ)szCaptionMsg);

    /******************************************************************/
    /* Load the message string from resources.                        */
    /******************************************************************/
    WinLoadString( hab,
                   prdd_ModHandle,
                   MessageID,
                   MessageLength,
                   (PSZ)szMessage );

    /******************************************************************/
    /* Put up the box and return the response.                        */
    /******************************************************************/
    return( WinMessageBox( HWND_DESKTOP,
                           hwnd,
                           (PSZ)szMessage,
                           (PSZ)szCaptionMsg,
                           WindowID,
                           MessageStyle) );
}




void prdm_RemoveMenuOptions(HWND hwnd)


{
#define TFUNC "prdm_RemMenuOpt"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    HWND     hwndSysMenu;      /* The handle for the system window    */
                               /* that goes with our dialog box (the  */
                               /* bar in the top left corner of the   */
                               /* dialog box)                         */

    /******************************************************************/
    /* Turn off the 'Close' and 'Task Manager' options on the system  */
    /* menu as these should not be selectable.  We need the handle to */
    /* this window to do this so call WinWindowFromID to get this.    */
    /******************************************************************/
    hwndSysMenu = WinWindowFromID( hwnd,
                                   FID_SYSMENU );

    WinSendMsg( hwndSysMenu,
                MM_SETITEMATTR,
                MPFROM2SHORT(SC_CLOSE, TRUE),
                MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED) );

//  WinSendMsg( hwndSysMenu,
//              MM_SETITEMATTR,
//              MPFROM2SHORT(SC_TASKMANAGER, TRUE),
//              MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED) );
}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_InitSourceBoxes                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND      hwnd          Current Window Handle.                   */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function processes the following DDT flags (hierarchically  */
/*   defined as shown):                                               */
/*                                                                    */
/*   DDT_VAR_PAPER_SOURCE_SUPPORT                                     */
/*                                                                    */
/*       There are radio buttons displayed in the dialog which need   */
/*       processing. They are processed in the following ways:        */
/*                                                                    */
/*       IF DDT_PAPER_SOURCE_GREYED then                              */
/*          they must be greyed as they are present in the dialog     */
/*          but not actually supported by this printer model.         */
/*       ELSE                                                         */
/*          the value that is highlighted is taken from:              */
/*          DMSsttings->SourceIndex                                   */
/*       ENDIF                                                        */
/*                                                                    */
/*       IF DDT_ENVELOPE_TRAY_SUPPORT then                            */
/*          There are two additional items in an additional feed      */
/*          dialog item, which must be highlighted from:              */
/*          DMSettings->AddedFeed                                     */
/*       ENDIF                                                        */
/*                                                                    */
/*       IF DDT_MULTIMEDIA_TRAY_SUPPORT then                          */
/*          There are four additional items in an additional feed     */
/*          dialog item, which must be highlighted from:              */
/*          DMSettings->AddedFeed                                     */
/*       ENDIF                                                        */
/*                                                                    */
/* 06/20/91 PD00183 : Created.                                        */
/*                                                                    */
/**********************************************************************/

VOID  prdm_InitSourceBoxes(HWND hwnd )

{
    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    RadCtrlType       Source;
    USHORT            SourceFlags;
    USHORT            DriverType;

    /******************************************************************/
    /* Get some variables, Note that the compiler optimises this sort */
    /* of code very well.                                             */
    /******************************************************************/
    SourceFlags = DDT[pDMSettings->PrinterType]->DDTSourceFlags;
    DriverType  = DDT[pDMSettings->PrinterType]->DDTDriverType;

    /******************************************************************/
    /* For each driver, set up a radio button control structure and   */
    /* then call the radio button control procedure to handle all of  */
    /* the enabling and the greying.                                  */
    /******************************************************************/

    /* (DriverType == DDT_IBM42XX_DRV)  */

    /**************************************************************/
    /* 42XX. The 4224 has four sources and no envelope stuff to   */
    /* worry about.                                               */
    /**************************************************************/
    Source.RadNumber    = 4;
    Source.RadItem[0]   = DB_RAD_42XX_F1;
    Source.RadItem[1]   = DB_RAD_42XX_F2;
    Source.RadItem[2]   = DB_RAD_42XX_F3;
    Source.RadItem[3]   = DB_RAD_42XX_F4;

    Source.RadGreyed    = (SourceFlags & DDT_SOURCE_GREYED);
    Source.RadHighlight = pDMSettings->SourceIndex;

    /**************************************************************/
    /* And set up the radio buttons.                              */
    /**************************************************************/
    (VOID) prdm_RadioButtonControl (hwnd, &Source);

    /******************************************************************/
    /* All done                                                       */
    /******************************************************************/
    return;
}



/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_RadioButtonsControl                               */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND           hwnd          Current Window Handle.              */
/*   lpRadCtrlType  lpRadioCtrl   Pointer to radio buttons.           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function processes the supplied radio buttons control       */
/*   structure as follows:                                            */
/*                                                                    */
/*   RadEnable - TRUE  radio buttons should end up enabled with the   */
/*                     RadHighlightItem highlighted. If the radio     */
/*                     buttons are disabled then they are enabled     */
/*                     befor selecting them.                          */
/*                                                                    */
/*             - FALSE radio button shsould end up disabled with the  */
/*                     RadHighlight item highligted. If the radio     */
/*                     buttons were already disabled then nothing is  */
/*                     changed meaning that the RadHighlight may not  */
/*                     be honored.                                    */
/*                                                                    */
/*                                                                    */
/* 06/20/91 PD00183 : Created.                                        */
/*                                                                    */
/**********************************************************************/
/*CON3201
VOID PASCAL FAR prdm_RadioButtonControl( hwnd,
                                         lpRadControl)

HWND            hwnd;
lpRadCtrlType   lpRadControl;
                            */
VOID prdm_RadioButtonControl(HWND            hwnd,
                             lpRadCtrlType   lpRadControl)

{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    USHORT       SourceFlags;
    USHORT       PaperSource;
    SHORT        i;
    HWND         DlgID;
    MRESULT      DlgResult;
    BOOL         CheckSwitch;
    BOOL         WinResult;     /* CON3201 some of the Win fns return BOOL */

    /******************************************************************/
    /* Use the first item in the radio buttons group to determine if */
    /* all the items are greyed because we either have greyed all the */
    /* items or none of them.                                         */
    /******************************************************************/
    DlgID = WinWindowFromID ( hwnd, lpRadControl->RadItem[0] );

    if (!lpRadControl->RadGreyed)
    {
        /**************************************************************/
        /* Required to end up enabled. Don't enable if they are       */
        /* already enabled.                                           */
        /**************************************************************/
        if (!WinIsWindowEnabled ( DlgID ) )
        {
            for (i=0;i<lpRadControl->RadNumber ;i++ )
            {
                DlgID = WinWindowFromID (hwnd, lpRadControl->RadItem[i]);
/*              DlgResult = WinEnableWindow (DlgID, TRUE);          CON3201 */
                WinResult = WinEnableWindow (DlgID, TRUE);
            }
        }

        /**************************************************************/
        /* Now select the highlighted item                            */
        /**************************************************************/
        for (i=0;i<lpRadControl->RadNumber ;i++ )
        {
            CheckSwitch = (lpRadControl->RadHighlight == i);

            DlgResult = WinSendDlgItemMsg (hwnd,
                                           lpRadControl->RadItem[i],
                                           BM_SETCHECK,
                                           (MPARAM)CheckSwitch,
                                           FNULL);
        }
    }
    else
    {
        /**************************************************************/
        /* Required to end up disbaled with a selected item chosen.   */
        /* But if it is already disabled then do nothing.             */
        /**************************************************************/
        if ( WinIsWindowEnabled ( DlgID ) )
        {
            for (i=0;i<lpRadControl->RadNumber ;i++ )
            {
                CheckSwitch = (lpRadControl->RadHighlight == i);

                DlgResult = WinSendDlgItemMsg (hwnd,
                                               lpRadControl->RadItem[i],
                                               BM_SETCHECK,
                                               (MPARAM)CheckSwitch,
                                               FNULL);

                DlgID = WinWindowFromID (hwnd, lpRadControl->RadItem[i]);
/*              DlgResult = WinEnableWindow (DlgID, FALSE);         CON3201 */
                WinResult = WinEnableWindow (DlgID, FALSE);
            }
        }
    }

    /******************************************************************/
    /* All done                                                       */
    /******************************************************************/
    return;

}


/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_FindFormInfo                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   ULONG            FormNum         Form index number               */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/* This function is given a form index number and tries to find the   */
/* form name, type and unit from the form data in DMData.             */
/**********************************************************************/
pFormInfoStruc  prdm_FindFormInfo(ULONG FormNum )

{
#define TFUNC "prdm_FindFormInfo"

   /*******************************************************************/
   /* Local Variables                                                 */
   /*******************************************************************/
   sForm  *       Form;                /* pointer to from data struc  */
   ULONG          i;                   /* loop index                  */
   PBYTE          pName;               /* pointer to the start of an  */
                                       /* item in the form data       */
   PBYTE          pItem;               /* pointer to step through the */
                                       /* form data                   */
   FormInfoStruc  FormInfo;            /* structure used to get form  */
                                       /* info from resources         */

   /*******************************************************************/
   /* Get the form data and set pName for the specified form number   */
   /*******************************************************************/
   Form = DMData.Forms;

   for ( i = 0; i < FormNum; i++ )
      Form = Form->NextForm;

   /*******************************************************************/
   /* Find the form type                                              */
   /*******************************************************************/
   FormInfo.FormType = Form->FormType;

   /*******************************************************************/
   /* Find the form name                                              */
   /*******************************************************************/
   pName = Form->FormData;

   for ( pItem = pName; *pItem != '\1'; pItem++ );

   *pItem = '\0';

   prdu_strcpy( (PBYTE) FormInfo.FormName, (PBYTE) pName );

   *pItem = '\1';

   /*******************************************************************/
   /* Find the form units                                             */
   /*******************************************************************/
   pItem++;

   FormInfo.FormUnits = *pItem++;

   /*******************************************************************/
   /* return the form info                                            */
   /*******************************************************************/
   return( &FormInfo );
}
#undef TFUNC


/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_FindFormNumber                                    */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   pFormInfoStruc   pFormInfo       Ptr to the form Info structure  */
/*                                    we're trying to match           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/* This function is given the form name, type and unit from           */
/* DriverData and tries to match it in the form data in DMData.       */
/* It returns the number of the form matched +1 if it found a match   */
/* and 0 if it didn't.                                                */
/**********************************************************************/
ULONG  prdm_FindFormNumber(pFormInfoStruc pFormInfo )

{
#define TFUNC "prdm_FindFormNumber"

   /*******************************************************************/
   /* Local Variables                                                 */
   /*******************************************************************/
   sForm     * Form;                   /* pointer to from data struc  */
   ULONG       i;                      /* loop index                  */
   PBYTE       pItem;                  /* pointer to the start of an  */
                                       /* item in the form data       */
   PBYTE       ItemPtr;                /* pointer to step through the */
                                       /* form data                   */

   /*******************************************************************/
   /* Check that if there is a existing form that matches.            */
   /*******************************************************************/
   for ( Form = DMData.Forms, i = 0;
         Form;
         Form = Form->NextForm, i++ )
   {
       /***************************************************************/
       /* Match the form type                                         */
       /***************************************************************/
       if ( Form->FormType == pFormInfo->FormType )
       {
           pItem = Form->FormData;

           /***********************************************************/
           /* The form name is delimited by a 1. Replace this with a  */
           /* zero for string compares, then replace zero back with   */
           /* 1 at the end.                                           */
           /***********************************************************/
           for ( ItemPtr = pItem; *ItemPtr != '\1'; ItemPtr++ );

           /***********************************************************/
           /* Match the form name                                     */
           /***********************************************************/
           *ItemPtr = '\0';
           if ( !prdu_strcmp( (PBYTE) pItem,
                              (PBYTE) pFormInfo->FormName ) )
           {
               /*******************************************************/
               /* Replace the zero with a one before we move to the   */
               /* next byte.                                          */
               /*******************************************************/
               *ItemPtr = '\1';
               ItemPtr++;

               /*******************************************************/
               /* Match the form units                                */
               /*******************************************************/
               if ( *ItemPtr++ == pFormInfo->FormUnits )
                    return((LONG)(i+1));
           }
           else
           {
               /*******************************************************/
               /* Replace the zero with a one                         */
               /*******************************************************/
               *ItemPtr = '\1';
           }
       }
   }

   /*******************************************************************/
   /* if nothing matches, return 0.                                   */
   /*******************************************************************/
   return(0L);
}
#undef TFUNC


/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_FindDfltFormNo                                    */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/* This function find the default form index number                   */
/**********************************************************************/
ULONG  prdm_FindDfltFormNo( )
{
#define TFUNC "prdm_FindDfltFormNo"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    lpDVTSourceList   pSourceInfo;     /* Source configurations list  */
    lpDVTSourceTray   pTrayInfo;       /* Tray list for the current   */
                                       /* source                      */

    /******************************************************************/
    /* If there is at least 1 automatic source                        */
    /******************************************************************/
    pSourceInfo  = DDT[pDMSettings->PrinterType]->DDTSourceList;
    pSourceInfo += pDMSettings->SourceIndex;
    if ( pSourceInfo->NoOfPaperTrays > 0 )
    {
        pTrayInfo  = pSourceInfo->SourceTrayList;
        return( DMData.ConnsInfo.AutoTrayForm[pTrayInfo->DMTrayUsage] );
    }
    else
    {
        /**************************************************************/
        /* If there is at least one form selected in manual           */
        /**************************************************************/
        if ( DMData.ConnsInfo.NoOfManualPaper > 0 )
        {
            return( DMData.ConnsInfo.pManualPaper[0] );
        }
        else
        {
            /**********************************************************/
            /* Use country dependent form                             */
            /**********************************************************/
            return( DMData.DefaultForm );
        }
    }
}
#undef TFUNC
