/*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 = PRDMENTR
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdm_EnterValues
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                         /* Convert to C/SET2    CON3201       */
#define INCL_DOSPROCESS                 /* Convert to C/SET2    CON3201       */
#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_WINPOINTERS
#include <os2.h>
#undef INCL_DOSPROCESS                  /* Convert to C/SET2    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_WINPOINTERS

#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

#define INCL_WINSHELLDATA
/* #include <pmshlp.h>                                              DLM01 */
#define INCL_WINSHELLDATA
#undef INCL_32                          /* Convert to C/SET2    CON3201       */

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

#include <prdconse.h>
#include <prdmcone.h>
#include <prddcone.h>

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

extern lpDDTType         DDT [];
extern DModeDataType     DMData;
extern lpDMSettings      pDMSettings;
extern CHAR              szMessage[SLEN_BOX_MESSAGE];
extern char              szCaption[40];
extern DMIniEntryType    DMIniEntry[LARGEST_NO_OF_PRINTERS];




/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_EnterValues                                       */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND   hwnd;      Handle of the dialog box                       */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called when the user has selected the ENTER     */
/*   button from one of the dialog boxes.  It attempts to write the   */
/*   data currently contained in that dialog box into the DMData and  */
/*   attached form data blocks.  If it is unable to do this then      */
/*   it returns an error (FALSE) so the user knows the data given is  */
/*   unacceptable and the printer data is kept valid.                 */
/*                                                                    */
/**********************************************************************/
#if 0
USHORT pascal prdm_EnterValues( hwnd )

HWND   hwnd;
#endif

USHORT prdm_EnterValues( HWND hwnd )                       /* CON3201 */

{
#define TFUNC "prdm_EntrValues"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT      i;            /* Loop control variable                */
    USHORT      WndId;        /* ID for a field in the dialog box     */
    MRESULT     DlgResult;    /* The result of a call to Win..        */
                              /* function                             */
    BYTE        Units;        /* The units which have been selected   */
    SHORT       Result;       /* Function call return values          */
    ULONG       Value;        /* Used to build up numbers from text   */
                              /* in text entry boxes                  */
 /* BYTE far *  cp; */        /* Pointer to a character for           */
                                                           /* CON3201 */
    BYTE     *  cp;           /* Pointer to a character for           */
                              /* manipulting strings                  */
    SHORT       FormLen;      /* The length of the form name from the */
                              /* dialog box                           */
    SHORT       EntryLen;     /* The length of an entry in a text box */
                              /* for a dimension                      */
    BOOL        Valid;        /* Determines whether the form name is  */
                              /* valid                                */
    BOOL        NonSpace;     /* At least one non-space char in name  */
    SHORT       Count;        /* Loop control variable                */
 /* sForm far * Form;    */   /* Pointers to form data structures for */
 /* sForm far * NewForm; */   /* stepping through the list of forms   */
                                                           /* CON3201 */
    sForm     * Form;         /* Pointers to form data structures for */
    sForm     * NewForm;      /* stepping through the list of forms   */
    BOOL        PassedDot;    /* Flag for converting text numbers     */
                              /* decimal places to numbers            */
    SHORT       NoOfDecPlaces;/* The number of decimal places we      */
                              /* store data to                        */
    PBYTE       PtrItemStart; /* pointer to start of form name        */
    PCHAR       ItemPtr;      /* pointer to step through form name    */
    USHORT      MsgId;        /* ID to be used for error message      */
    ULONG       Width;        /* The width and ...                    */
    ULONG       Height;       /*  ... height of the defined form      */
    ULONG       LeftClip;     /* The left and ...                     */
    ULONG       RightClip;    /*  ... right clip limit                */
    ULONG       BottomClip;   /* The bottom and ...                   */
    ULONG       TopClip;      /*  ... top clip limit                  */
    lpDDTType   pDDT;         /* Pointer to DDT for this printer      */
    CHAR        DecimalPoint[3]; /* Country-specific decimal point    */
                                 /* string, for form name checking.   */
    ULONG       HorzMargin;   /* The vertical and ...                 */
    ULONG       VertMargin;   /*  ... Horizontal margins              */
    USHORT      TopMargin;
    USHORT      RightEdge;
    ULONG       VertTopMargin;/*  PD00765                             */
    lpDVTSourceList   pSourceInfo;
                                /* Current source configeration       */
    BOOL        AdjTopClip;     /* Set on if there is a minimum top   */
                                /* clip                               */
    USHORT      MaxRetLen;
    PBYTE       StrPtr;
    USHORT      Number;


    /******************************************************************/
    /* Switch according to which dialog box it is.                    */
    /******************************************************************/
    switch ( DMData.DialogId )
    {
        case DB_ADD_FORM:
        case DB_CHANGE_FORM:
        case DB_ADD_FORM_MARGIN:
        case DB_CHANGE_FORM_MARGIN:
            /**********************************************************/
            /* Initialise the form buffer to spaces as these are our  */
            /* delimeters.                                            */
            /**********************************************************/
            for ( Count = 0; Count < FORM_DATA_LENGTH; Count++ )
                DMData.FormBuffer[Count] = ' ';

            Number = 0;

            /**********************************************************/
            /* Set up the DDT pointer and the units.                  */
            /**********************************************************/
            pDDT = DDT[pDMSettings->PrinterType];
            Units = pDDT->DDTDefinedForms
                                 [DMData.FormTemplateNum].FormData[0];

            /**********************************************************/
            /* Get the form name from the entry field and check it    */
            /* is valid - ie at least one character and all           */
            /* alphabetical characters.                               */
            /**********************************************************/
            FormLen = WinQueryDlgItemText( hwnd,
                                           DB_TXT_FORM_NAME,
                                           FORM_NAME_LENGTH,
                                           (PSZ)DMData.FormBuffer );

            /**********************************************************/
            /* Remove any trailing spaces in the form name.           */
            /**********************************************************/
            for ( i = FormLen - 1; i; i-- )
            {
                if ( DMData.FormBuffer[i] == ' ' )
                    DMData.FormBuffer[i] = '\0';
                else
                    break;
            }

            Valid = ( DMData.FormBuffer[0] != '\0' );

            /**********************************************************/
            /* The string is null terminated hence *cp test will find */
            /* end. Validate the form name: allow all characters      */
            /* with ASCII code greater than 32 (space) except '*', ';'*/
            /* and '='. If the decimal point charcter is a full stop  */
            /* then commas are also disallowed.                       */
            /*****************e****************************************/
            NonSpace = FALSE;

/* CON3201 ************************************************************/
/* WinQueryProfileString no longer supported must use Prf             */
//          if (TRUE)   /* @@@ use Win, not Prf call */
//          {
//              if ( !WinQueryProfileString( hab,
//                               "PM_National",   /* application name */
//                               "sDecimal",      /* key name         */
//                               ".",             /* default          */
//                               DecimalPoint,    /* returned value   */
//                               3 ) )            /* maximum length   */
//              {
//                  TRACE8(TFUNC,"Error in INI file",FNULL,0);
//                  return (FALSE);
//              }
//          }
//          else
//          {
//              /******************************************************/
//              /* Prf call uses OS2.INI if HINI_USERPROFILE          */
//              /* It uses OS2SYS.INI if HINI_SYSTEMPROFILE           */
//              /******************************************************/
//              if ( !PrfQueryProfileString( HINI_USERPROFILE,
//                               "PM_National",   /* application name */
//                               "sDecimal",      /* key name         */
//                               ".",             /* default          */
//                               DecimalPoint,    /* returned value   */
//                               3L ) )           /* maximum length   */
//              {
//                  TRACE8(TFUNC,"Error in INI file",FNULL,0);
//                  return (FALSE);
//              }
//          }
/* CON3201 - Must use PrfQueryProfileString                      */
            if ( !PrfQueryProfileString( HINI_USERPROFILE,
                            "PM_National",   /* application name */
                            "sDecimal",      /* key name         */
                            ".",             /* default          */
                            DecimalPoint,    /* returned value   */
                            3L ) )           /* maximum length   */
            {
                TRACE8(TFUNC,"Error in INI file",FNULL,0);
                return (FALSE);
            }

            for ( cp = DMData.FormBuffer; *cp && Valid; cp++ )
            {
                Valid = !( ( *cp < ' ' )  || ( *cp == '=' ) ||
                           ( *cp == '*' ) || ( *cp == ';' ) ||
                           ((*cp == ',') && (*DecimalPoint == '.')) );
                if ( *cp > ' ' )
                    NonSpace = TRUE;
            }

            /**********************************************************/
            /* The form name must contain at least one non-space      */
            /* character.                                             */
            /**********************************************************/
            if ( NonSpace == FALSE )
                Valid = FALSE;

            if ( !Valid )
            {
                /******************************************************/
                /* The form name is invalid.                          */
                /******************************************************/
                MsgId = IDS_INV_FORM_NAME;
                WndId = DB_TXT_FORM_NAME;
                goto MSGID_ERR_EXIT;
            }

            /**********************************************************/
            /* Check that the name is not already in use.             */
            /**********************************************************/
            for ( Form = DMData.Forms, Count = 0;
                  Form;
                  Form = Form->NextForm, Count++ )
            {
                PtrItemStart = Form->FormData;

                for ( ItemPtr = PtrItemStart;
                      *ItemPtr != '\1';
                      ItemPtr++ );

                /******************************************************/
                /* Check if the names match.                          */
                /******************************************************/
                *ItemPtr = '\0';
                Valid = prdu_strcmp( (PBYTE)PtrItemStart,
                                     (PBYTE)DMData.FormBuffer );
                *ItemPtr = '\1';

                if ( !Valid )
                {
                    /**************************************************/
                    /* We have found a duplicate form name. If we are */
                    /* changing a form, and the matching form is that */
                    /* used as the template then it is not an error.  */
                    /**************************************************/
                    if ( ((DMData.DialogId == DB_CHANGE_FORM) ||
                          (DMData.DialogId == DB_CHANGE_FORM_MARGIN)) &&
                         ((USHORT)pDMSettings->SelectedForm == Count) )
                    {
                        continue;
                    }
                    else
                    {
                        MsgId = IDS_SAME_NAME,
                        WndId = DB_TXT_FORM_NAME;
                        goto MSGID_ERR_EXIT;
                    }
                }
            }

            /**********************************************************/
            /* Put in the name delimiter of \1 followed by the units. */
            /**********************************************************/
            DMData.FormBuffer[FormLen++] = '\1';
            DMData.FormBuffer[FormLen++] = Units;

            /**********************************************************/
            /* The space delimeter                                    */
            /**********************************************************/
            DMData.FormBuffer[FormLen++] = ' ';

            /**********************************************************/
            /* MsgId is set to a non-zero value below if there is a   */
            /* dud entry field.                                       */
            /**********************************************************/
            MsgId = 0;

            /**********************************************************/
            /* Pick up the top margin, non-zero for the 4224 printer. */
            /* This is used to check the top clip limit.              */
            /**********************************************************/
            pSourceInfo  = DDT[pDMSettings->PrinterType]->DDTSourceList;
            pSourceInfo += pDMSettings->SourceIndex;

            /**********************************************************/
            /* Adjust for envelope or multimedia options. Note that   */
            /* this is not in fact necessary, as TopMargin is always  */
            /* zero for 4019 printers.                                */
            /**********************************************************/
            if ( pDMSettings->AddedFeed == FD_ENVELOPE )
                pSourceInfo += 1;
            else if ( pDMSettings->AddedFeed == FD_MULTIMEDIA )
                pSourceInfo += 2;
            else if ( pDMSettings->AddedFeed == FD_100_SHEET )
                pSourceInfo += 3;

            AdjTopClip = ( pSourceInfo->TopMargin != 0 );

            /**********************************************************/
            /* If this is a laser printer then we use VertMargin and  */
            /* HorzMargin to force minimum margins; if not (so        */
            /* non-printable margin flag not on) use RightEdge and    */
            /* TopMargin.                                             */
            /**********************************************************/
            if ( pDDT->DDTFormFlags & DDT_NON_PRINTABLE_MARGIN )
            {
                if ( Units == INCHES )
                {
                    HorzMargin = 25;

                    if ( pDDT->DDTDriverType == DDT_IBM4019_DRV )
                        VertMargin = 17;
                    else                 /*  3816  */
                        VertMargin = 25;
                    VertTopMargin = VertMargin;            /* PD00765 */
                    if (( pDDT->DDTDriverType == DDT_IBM42XX_DRV ) &&
                        ( pDMSettings->PrinterType == IBM_PRONTO )    )
                    {
                        VertMargin = 50;                   /* PD00764 */
                        VertTopMargin = 11;                /* PD00765 */
                    }
                }
                else
                {
                    HorzMargin = 64;

                    if ( pDDT->DDTDriverType == DDT_IBM4019_DRV )
                    {
                        VertMargin = 44;

                        /**********************************************/
                        /* New A4 clips on 4019.                      */
                        /**********************************************/
                        if (DMData.FormTemplateNum == A4_FORM)
                           HorzMargin = 34;
                    }
                    else                 /*  3816  */
                        VertMargin = 64;
                    VertTopMargin = VertMargin;            /* PD00765 */
                    if (( pDDT->DDTDriverType == DDT_IBM42XX_DRV ) &&
                        ( pDMSettings->PrinterType == IBM_PRONTO )    )
                    {
                        VertMargin = 127;
                        VertTopMargin = 28;
                    }

                    /**********************************************************/
                    /*  PD00754 : Incorrect left clip value for ExecJet       */
                    /**********************************************************/
                    if ( pDDT->DDTDriverType == DDT_IBM42XX_DRV )
                    {
                      if (pDMSettings->PrinterType == IBM_EXECJET)
                      {
                        if ( (DMData.FormTemplateNum == A4_FORM) ||
                             (DMData.FormTemplateNum == 5 ) ||
                             (DMData.FormTemplateNum == 9 ) )
                        {
                            HorzMargin = 34;
                        }
                      }
                      else
                      {
                        if ( (DMData.FormTemplateNum == A4_FORM) ||
                             (DMData.FormTemplateNum == 2 ) )
                        {
                            HorzMargin = 50;
                        }
                      }
                    }
               }
            }
            else
            {
                if ( Units == (BYTE)INCHES )
                {
                    /**************************************************/
                    /* Units are hundredths of inches.                */
                    /**************************************************/
                    TopMargin = pSourceInfo->TopMargin;

                    /**************************************************/
                    /* MaxPrintWidth units are tenths of inches !     */
                    /**************************************************/
                    RightEdge = pDDT->DDTMaxPrintWidth * 10;
                }
                else
                {
                    /**************************************************/
                    /* Units are tenths of millimetres.               */
                    /**************************************************/
                    TopMargin = (pSourceInfo->TopMargin * 254) / 100;

                    /**************************************************/
                    /* MaxPrintWidth units are tenths of inches !     */
                    /**************************************************/
                    RightEdge = (pDDT->DDTMaxPrintWidth * 254) / 10;
                }
            }

            /**********************************************************/
            /* Get the rest of the form dimensions.  Note reliance on */
            /* window IDs being every second number after FORM_WIDTH  */
            /* - see values in PRDMCONE.H.                            */
            /**********************************************************/
            for ( WndId = DB_TXT_FORM_WIDTH;
                  WndId <= DB_TXT_TOP_CLIP_LIMIT;
                  WndId += 1 )
            {
                EntryLen = WinQueryDlgItemText(
                                    hwnd,
                                    WndId,
                                    NUMBER_LENGTH + 1,
                                    (PSZ)&DMData.FormBuffer[FormLen] );

                if ( WndId == DB_TXT_FORM_WIDTH ||
                     WndId == DB_TXT_FORM_HEIGHT )
                {
                    /**************************************************/
                    /* First handle width and height - a null string  */
                    /* is an error.                                   */
                    /**************************************************/
                    if ( !EntryLen )
                    {
                        TRACE4(TFUNC, "No form dim", FNULL, 0);
                        MsgId = IDS_NO_DIMENSION;
                        goto MSGID_ERR_EXIT;
                    }
                }
                /*.. if (WndId == FORM_WIDTH || WndId == FORM_HEIGHT) */

                /******************************************************/
                /* Now, for all numbers we must translate from text   */
                /* (ie '12.34') to a number in the form we store the  */
                /* dimension in.  Start with a Value of 0 and a       */
                /* NoOfDecPlaces which is how many places we shift    */
                /* a number left to store it as a whole number (this  */
                /* is different for inches and millimetres).  We go   */
                /* through the number accumulating digits to give us  */
                /* the Value, PassedDot tells us that we are in       */
                /* decimal places and we only accept NoOfDecPlaces    */
                /* digits after the point before breaking from the    */
                /* loop.  After we have accumulated all the digits    */
                /* we then ensure the number is correctly aligned by  */
                /* shifting it left NoOfDecPlaces times (ie once      */
                /* for every digit after the point we could store but */
                /* have not).                                         */
                /******************************************************/
                Value = 0;
                NoOfDecPlaces = (Units == INCHES)
                             ? MAX_DEC_PLACES_INCHES: MAX_DEC_PLACES_MM;
                PassedDot = FALSE;

                for ( cp = &DMData.FormBuffer[FormLen]; *cp; cp++ )
                {
                    /**************************************************/
                    /* Trap as invalid a second decimal point.        */
                    /**************************************************/
                    if ( PassedDot && (*cp == DMData.DecimalPoint) )
                        break;

                    /**************************************************/
                    /* Note --NoOfDecPlaces will only be executed     */
                    /* if PassedDot is TRUE.                          */
                    /* Skip over trailing zeroes. Any further non-null*/
                    /* characters mean the entry is invalid.          */
                    /**************************************************/
                    if ( PassedDot && (--NoOfDecPlaces < 0) )
                    {
                        NoOfDecPlaces = 0;
                        while ( *cp == '0') cp++;
                        break;
                    }

                    /**************************************************/
                    /* Character must be a digit.                     */
                    /* Can't use library function to multiply longs   */
                    /* so add 9 Value instead of *10                  */
                    /**************************************************/
                    if ( *cp >= '0' && *cp <= '9' )
                    {
                        Value += Value + Value + Value +
                                 Value + Value + Value +
                                 Value + Value + Value + *cp - '0';
                    }
                    else if ( *cp == DMData.DecimalPoint )
                    {
                        PassedDot = TRUE;
                    }
                    else
                    {
                        break;
                    }
                }
                /*.. for (cp=&DMData.FormBuffer[FormLen]; *cp; cp++) .*/

                if ( *cp )
                {
                    /**************************************************/
                    /* If *cp != 0 then the break from the loop above */
                    /* was not caused by the null terminator so there */
                    /* is an error.  Report this and return FALSE.    */
                    /**************************************************/
                    TRACE4(TFUNC, "Invalid Input", FNULL, 0);
                    MsgId = IDS_INVALID_INPUT;
                    goto MSGID_ERR_EXIT;
                }
                else
                {
                    /**************************************************/
                    /* Replace the null terminator with a space -     */
                    /* this ensures there are no unexpected nulls in  */
                    /* the Formdata buffer.                           */
                    /**************************************************/
                    *cp = ' ';
                }

                while ( NoOfDecPlaces-- )
                {
                    /**************************************************/
                    /* Can't use library function to multiply longs   */
                    /* so add Value 9 times instead of *10            */
                    /**************************************************/
                    Value += Value + Value + Value +
                             Value + Value + Value +
                             Value + Value + Value;
                }

                /******************************************************/
                /* There are 7 bytes available for the value string   */
                /* so the maximum inches is 9999.99 and the maximum   */
                /* millimetres is 99999.9. If Value exceeds this      */
                /* report an error.                                   */
                /******************************************************/
                if ( Value >= 1000000 )
                {
                    TRACE4(TFUNC, "Invalid Input", FNULL, 0);
                    MsgId = IDS_INVALID_INPUT;
                    goto MSGID_ERR_EXIT;
                }

                /******************************************************/
                /* Set variable depending on form field we are in and */
                /* perform error checking on entered value.           */
                /******************************************************/
                switch (WndId )
                {
                    case DB_TXT_FORM_WIDTH:
                        Width = Value;
                        break;

                    case DB_TXT_FORM_HEIGHT:
                        Height = Value;
                        break;

                    case DB_TXT_LFT_CLIP_LIMIT:
                        LeftClip = Value;

                        if ( pDDT->DDTFormFlags &
                                            DDT_NON_PRINTABLE_MARGIN )
                        {
                            if ( LeftClip < HorzMargin )
                                MsgId = IDS_CLIP_IN_UNPRINT;
                        }
                        break;

                    case DB_TXT_RHT_CLIP_LIMIT:
                        RightClip = Value;

                        if ( pDDT->DDTFormFlags &
                                            DDT_NON_PRINTABLE_MARGIN )
                        {
                            if (pDDT->DDTDriverType != DDT_IBM42XX_DRV)
                            {
                                if ( RightClip > (Width - HorzMargin) )
                                    MsgId = IDS_CLIP_IN_UNPRINT;
                            }
                            else
                            {
                                /**********************************************/
                                /*  PD00754:Do checks for correct message on  */
                                /*  the 4070 and 4072.                        */
                                /**********************************************/
                                if (Units == INCHES)
                                {
                                    if (pDMSettings->PrinterType == IBM_EXECJET)
                                    {
                                        /**************************************/
                                        /*  ((13.6 in)*100 + (0.25 in)*100)   */
                                        /*  The 0.25 is the left clip on the  */
                                        /*  4072.                             */
                                        /**************************************/
                                        RightEdge = 1385;
                                    }
                                    else
                                    {
                                        /**************************************/
                                        /*  ((80.0 in)*100 + (0.25 in)*100)   */
                                        /*  The 0.25 is the left clip on the  */
                                        /*  4070.                             */
                                        /**************************************/
                                        RightEdge = 825;
                                    }
                                }
                                else
                                {
                                    if (pDMSettings->PrinterType == IBM_EXECJET)
                                    {
                                        /**************************************/
                                        /*  ((13.6 in)*254 + (0.25 in)*254)   */
                                        /*  The 0.25 is the left clip on the  */
                                        /*  4070.                             */
                                        /**************************************/
                                        RightEdge = 3518;
                                    }
                                    else
                                    {
                                        /**************************************/
                                        /*  ((80.0 in)*254 + (0.25 in)*254)   */
                                        /*  The 0.25 is the left clip on the  */
                                        /*  4070.                             */
                                        /**************************************/
                                        RightEdge = 2096;
                                    }
                                }

                                if (RightClip > RightEdge)
                                {
                                    MsgId = IDS_RIGHT_MARG_OVERLAP;
                                    Number = RightEdge;
                                }
                            }
                        }
                        else
                        {
                            if ( RightClip > RightEdge )
                            {
                                MsgId = IDS_RIGHT_MARG_OVERLAP;
                                Number = RightEdge;
                            }
                        }

                        /**********************************************/
                        /* Check that the clip limit lies on the page */
                        /**********************************************/
                        if ( RightClip > Width )
                        {
                            MsgId = IDS_INVALID_CLIP;
                            Number = 0;
                        }

                        if ( RightClip <= LeftClip )
                        {
                            MsgId = IDS_HORZ_CLIP_OVERLAP;
                            Number = 0;
                        }
                        break;

                    case DB_TXT_BTM_CLIP_LIMIT:
                        BottomClip = Value;

                        /**********************************************/
                        /*  PD00764 : Check Bottom clip on 4070       */
                        /**********************************************/
                        if ((pDDT->DDTFormFlags & DDT_NON_PRINTABLE_MARGIN) &&
                            ((pDDT->DDTDriverType != DDT_IBM42XX_DRV ) ||
                             (pDMSettings->PrinterType == IBM_PRONTO )    )   )
                        {
                            if ( BottomClip < VertMargin )
                                MsgId = IDS_CLIP_IN_UNPRINT;
                        }
                        else
                        {
                             /*************************************************/
                             /*  PD00749 : Initialize TopMargin before        */
                             /*  checking it against the bottom clip.         */
                             /*************************************************/
                            if ( Units == (BYTE)INCHES )
                            {
                                /**********************************************/
                                /* Units are hundredths of inches.            */
                                /**********************************************/
                                TopMargin = pSourceInfo->TopMargin;
                            }
                            else
                            {
                                /**********************************************/
                                /* Units are tenths of millimetres.           */
                                /**********************************************/
                                TopMargin = (pSourceInfo->TopMargin * 254) / 100;
                            }

                            /**************************************************/
                            /*  INKJET : You must check the bottom clip value */
                            /*  entered and make sure it is not less than the */
                            /*  minimum clip level of the printer.            */
                            /**************************************************/
                            if ( AdjTopClip &&
                                      (BottomClip < TopMargin) &&
                                      (pDDT->DDTFormFlags &
                                                     DDT_VAR_BOTTOM_CLIP) )
                            {
                                MsgId = IDS_CLIP_IN_UNPRINT;
                                Number = 0;
                            }
                        }
                        break;

                    case DB_TXT_TOP_CLIP_LIMIT:
                        TopClip = Value;

                        /**********************************************/
                        /* Check that the clip limit lies on the page */
                        /**********************************************/
                        /*  PD00765 : Check Top clip on 4070          */
                        /**********************************************/
                        if ((pDDT->DDTFormFlags & DDT_NON_PRINTABLE_MARGIN) &&
                            ((pDDT->DDTDriverType != DDT_IBM42XX_DRV ) ||
                             (pDMSettings->PrinterType == IBM_PRONTO )    )   )
                        {
                            if (TopClip > (Height - VertTopMargin))
                                MsgId = IDS_CLIP_IN_UNPRINT;
                        }
                        else
                        {
                            /**************************************************/
                            /*  INKJET : If it is the 4072 then the TopMargin */
                            /*  field is actually the bottom margin value.    */
                            /**************************************************/
                            if ( AdjTopClip &&
                                      (TopClip > Height - TopMargin) &&
                                      (!(pDDT->DDTFormFlags &
                                                     DDT_VAR_BOTTOM_CLIP)) )
                            {
                                MsgId = IDS_TOP_MARGIN_OVERLAP;
                                Number = (USHORT)Height - TopMargin;
                            }
                        }

                        if ( TopClip > Height )
                        {
                            MsgId = IDS_INVALID_CLIP;
                            Number = 0;
                        }

                        if ( TopClip <= BottomClip )
                        {
                            MsgId = IDS_VERT_CLIP_OVERLAP;
                            Number = 0;
                        }
                        break;
                }
                /* switch ............... WinId ..................... */


                /******************************************************/
                /* If an error has been detected display the error    */
                /* and return indicating the entering of values has   */
                /* failed. The focus is set to the invalid field.     */
                /******************************************************/
                if ( Number )
                    goto MSGID_ERR_EXIT_2;
                if ( MsgId )
                    goto MSGID_ERR_EXIT;

                /******************************************************/
                /* Now write the number into our form data as text    */
                /* (without any excess decimal places) and add the    */
                /* terminating space.  FormLen is updated to the      */
                /* position to start the next entry from.             */
                /******************************************************/
                cp = &DMData.FormBuffer[FormLen];
                NoOfDecPlaces = (Units == INCHES)
                           ? MAX_DEC_PLACES_INCHES : MAX_DEC_PLACES_MM;

                prdm_TextFromNumeric( Value,
                                      &cp,
                                      (USHORT)NoOfDecPlaces );

                *cp++ = ' ';
                FormLen = (USHORT)
                            ((ULONG)cp -(ULONG)(PBYTE)DMData.FormBuffer);

            }
            /*.. for ( WndId = FORM_WIDTH; WndId <= ...each form dim. */

            /**********************************************************/
            /* Set up form name as null terminated for the coming     */
            /* operations.                                            */
            /**********************************************************/
            for ( cp = DMData.FormBuffer; *cp != '\1'; cp++ )
                ;
            *cp = '\0';

            if ( DMData.DialogId == DB_CHANGE_FORM ||
                 DMData.DialogId == DB_CHANGE_FORM_MARGIN )
            {
                /******************************************************/
                /* We are editing an old form so send the new name    */
                /* to the listbox in the CURRENT_OPTIONS dialog box   */
                /* (Note DMData.hwndMain in WinSendDlgItemMsg call)   */
                /* and deselect all items in that listbox (the current*/
                /* form will be selected later).  Also set up Form    */
                /* to the current form for following write of the data*/
                /* from the FormBuffer to the current form.           */
                /******************************************************/
                TRACE4( TFUNC, "Edit", FNULL, 0);

                Form = DMData.Forms;

                for ( Count=0;
                      Count < (USHORT)pDMSettings->SelectedForm;
                      Count++ )
                {
                    Form = Form->NextForm;
                }

                DlgResult = WinSendDlgItemMsg(
                                DMData.hwndMain,
                                DB_LST_DEFINED_FORMS,
                                LM_SETITEMTEXT,
                                (MPARAM)pDMSettings->SelectedForm,
                                (MPARAM)(ULONG)(PSZ)DMData.FormBuffer );

                DlgResult = WinSendDlgItemMsg( DMData.hwndMain,
                                               DB_LST_DEFINED_FORMS,
                                               LM_SELECTITEM,
                                               (MPARAM)(ULONG)LIT_NONE,
                                               (MPARAM)(ULONG)TRUE );
            }
            /*.. if ( DMData.DialogId == DB_CHANGE_FORM) .............*/

            else
            {
                /******************************************************/
                /* We are adding a new form so we must obtain memory  */
                /* for the form data via SSALLOCSEG, append this     */
                /* new form data block to the end of our list set its */
                /* NextForm pointer to NULL and set Form to be the    */
                /* current form for the following write of data.      */
                /* Then insert this form name at the end of the list  */
                /* in the CURRENT_OPTIONS listbox and determine its   */
                /* Form Number from the result of this call. This     */
                /* becomes the selected form.                         */
                /******************************************************/
            /* CON3201 ************************************************/
            /*  Result = SSALLOCSEG ( sizeof(sForm),                  */
            /*                        &SELECTOROF(NewForm), 0 );      */
            /**********************************************************/

                Result = SafeSSALLOCMEM ( &NewForm,
                                       sizeof(sForm), 0 );

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

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

                for ( Form = DMData.Forms; Form->NextForm; )
                {
                     Form = Form->NextForm;
                }

                Form->NextForm = NewForm;
                Form = NewForm;
                Form->NextForm = FNULL;

                /******************************************************/
                /* Increase the number of forms for the new form      */
                /* added.                                             */
                /******************************************************/
                pDMSettings->NumberOfForms++;

                /******************************************************/
                /* Deselect forms.                                    */
                /******************************************************/
                DlgResult = WinSendDlgItemMsg(
                                DMData.hwndMain,
                                DB_LST_DEFINED_FORMS,
                                LM_INSERTITEM,
                                (MPARAM)(ULONG)LIT_END,
                                (MPARAM)(ULONG)(PSZ)DMData.FormBuffer );


                /******************************************************/
                /* Set up that the added form is going to be the      */
                /* current selected form.                             */
                /******************************************************/
                pDMSettings->SelectedForm = SHORT1FROMMR(DlgResult);
            }
            /*.. else ! ( DMData.DialogId == DB_CHANGE_FORM) .........*/

            /**********************************************************/
            /* Restore the delimiter after the form name in           */
            /* FormBuffer after previous operations.                  */
            /**********************************************************/
            *cp = '\1';

            /**********************************************************/
            /* Set the form type and ID from the template used.       */
            /**********************************************************/
            Form->FormType =
                 pDDT->DDTDefinedForms[DMData.FormTemplateNum].FormType;
            Form->FormID =
                 pDDT->DDTDefinedForms[DMData.FormTemplateNum].FormId;

            /**********************************************************/
            /* All the data entered for the form is valid and can now */
            /* be written into the OS2.INI file buffer.               */
            /**********************************************************/
            TRACE4( TFUNC, "Contents", (DPTR)DMData.FormBuffer, 12);

            prdu_memcpy( (PBYTE)Form->FormData,
                         (PBYTE)DMData.FormBuffer,
                         FORM_DATA_LENGTH );

            /**********************************************************/
            /* Select the new form in the CURRENT_OPTIONS listbox.    */
            /**********************************************************/
            DlgResult = WinSendDlgItemMsg(
                             DMData.hwndMain,
                             DB_LST_DEFINED_FORMS,
                             LM_SELECTITEM,
                             (MPARAM)(ULONG)pDMSettings->SelectedForm,
                             (MPARAM)(ULONG)TRUE );

            /**********************************************************/
            /* Tell prdm_MainDlgProc that the ENTER has been handled  */
            /* succesfully so it can fall through to its CANCEL case. */
            /**********************************************************/
            return (TRUE);
            break;

        case DB_DLG_PPPROS:
        case DB_DLG_PP4224:
        case DB_DLG_PP2300:
        case DB_DLG_PP2300_2:
        case DB_DLG_PPEXECJET:
        case DB_DLG_PPPRONTO:
        case DB_DLG_PPINKJET:
            /**********************************************************/
            /* Tell prdm_MainDlgProc that the ENTER has been handled  */
            /* succesfully if the INI entry is written OK.            */
            /**********************************************************/
            if ( prdm_WriteIniEntry( pDMSettings->PrinterType,
                                     hwnd ) != OK )
                return (FALSE);
            else
                return (TRUE);

            break;

    }
    /*.. switch (DMData.DialogId) ....................................*/


MSGID_ERR_EXIT_2:
    /******************************************************************/
    /* One of the entry fields is dud - inform the user,              */
    /* reset the focus and return FALSE.                              */
    /******************************************************************/
    TRACE6(TFUNC, "MsgId_Err_Exit_2", FNULL, 0);

    WinLoadString( hab,
                   DMData.HModule,
                   MsgId,
                   SLEN_BOX_MESSAGE,
                   (PSZ)szMessage );

    /******************************************************************/
    /* Now append Number (margin or printable width) onto the string. */
    /* Then add the units.                                            */
    /******************************************************************/
    StrPtr = szMessage + prdu_strlen(szMessage);

    NoOfDecPlaces = (Units == INCHES)
               ? MAX_DEC_PLACES_INCHES : MAX_DEC_PLACES_MM;

    prdm_TextFromNumeric( (ULONG)Number,
                          &StrPtr,
                          (USHORT)NoOfDecPlaces);

    *(StrPtr++) = ' ';

    *(StrPtr) = '\0';

    MaxRetLen = SLEN_BOX_MESSAGE - prdu_strlen(szMessage);

    WinLoadString( hab,
                   DMData.HModule,
                   (Units==INCHES)? IDS_INCHES : IDS_MILLIMETERS,
                   MaxRetLen,
                   (PSZ)StrPtr );

    /******************************************************************/
    /* Note second half is MsgId + 1: see mcone.h                     */
    /******************************************************************/
    StrPtr = szMessage + prdu_strlen(szMessage);
    MaxRetLen = SLEN_BOX_MESSAGE - prdu_strlen(szMessage);
    WinLoadString( hab,
                   DMData.HModule,
                   MsgId + 1,
                   MaxRetLen,
                   (PSZ)StrPtr );

    WinMessageBox( HWND_DESKTOP,
                   hwnd,
                   (PSZ)szMessage,
                   (PSZ)szCaption,
                   WndId,
                   MB_OK | MB_ICONEXCLAMATION );

/*  DlgResult = WinSetFocus( HWND_DESKTOP,                            CON3201 */
                WinSetFocus( HWND_DESKTOP,
                             WinWindowFromID(hwnd, WndId) );

    return (FALSE);

MSGID_ERR_EXIT:
    /******************************************************************/
    /* One of the entry fields is dud - inform the user,              */
    /* reset the focus and return FALSE.                              */
    /******************************************************************/
    TRACE6(TFUNC, "MsgId_Err_Exit", FNULL, 0);

    WinLoadString( hab,
                   DMData.HModule,
                   MsgId,
                   SLEN_BOX_MESSAGE,
                   (PSZ)szMessage );

    WinMessageBox( HWND_DESKTOP,
                   hwnd,
                   (PSZ)szMessage,
                   (PSZ)szCaption,
                   WndId,
                   MB_OK | MB_ICONEXCLAMATION );

/*  DlgResult = WinSetFocus( HWND_DESKTOP,                            CON3201 */
                WinSetFocus( HWND_DESKTOP,
                             WinWindowFromID(hwnd, WndId) );

    return (FALSE);

}
#undef TFUNC

