/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Microsoft 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 = PSOURCE.C
 *
 * DESCRIPTIVE NAME = POSTSCRIPT DRIVER SOURCE FILE
 *
 *
 * VERSION = V2.0
 *
 * DATE
 *
 * DESCRIPTION : This Module contains support routines for raising
 *               printer configuration dialog boxes.
 *               Opens a print set dialog box and prompts user to perform
 *               print settings.The following characteristics can be set:-
 *               Custom Paper type, The type of paper for various Input bins,                
 *
 *
 *
 *
 *
 * FUNCTIONS  :  CustomSize
 *               InitDefineForms
 *               AddToIni
 *               SetupProc
 *
 *
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define  INCL_WIN
#define  INCL_PM
#include <os2.h>
#include <bseerr.h>
#include <string.h>
#include "inc\ppdialog.h"
#include "inc\fileext.h"
#include "inc\config.h"
#include "inc\dlgproc.h"
#include "inc\pspagtun.h"             /* V2.174057  Page Tuning */
#define  INCL_GENPLIB_MEMORY
#include <genplib.h>

#define  INCHES        0
#define  CMS           1
#define  POINTS        2

extern PSZ GetDefaultPageSize( PDESPPD, PBYTE );
extern PBYTE StringTable[MAX_STRINGS];
extern PVOID pProcessHeap;
extern PFORMSTRUCT GetImageableArea( SHORT, PFORMSTRUCT, PDESPPD, PBYTE );
extern INT  _Optlink CompareRealNames( PSZ, PSZ ); /*            */

VOID InitDefineForms(HWND,PB *);
ULONG PostMsgBox(HMODULE,SHORT,SHORT,SHORT);

/*            */
extern VOID DisplayTranslationString( HWND, PSZ, UINT );

/***************************************************************************
 *
 * FUNCTION NAME = CustomSize
 *
 * DESCRIPTION   = This routine is called to check the width and height
 *                 of the current custom paper size passed in by the
 *                 caller. This routine returns TRUE, and saves the size
 *                 in the configuration data if all is well. Otherwise
 *                 it posts a message box, letting the user know where
 *                 the problem lies.
 *
 * INPUT         = HWND     hWnd
 *                 PCNFDATA pcnfData
 *                 SHORT   ushUnits
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = The address of a DDC, or INVALID_ADDRESS for failure.
 *
 * RETURN-ERROR  = INVALID_ADDRESS
 *
 ****************************************************************************/

BOOL CustomSize( HWND hWnd, PCNFDATA pcnfData, SHORT ushUnits )
{
  SHORT i, j;
  SHORT sHeight, sHeightFrac; /*
                             **  pair of integers to contain integral &
                             **  fract part
                             */
  SHORT sWidth, sWidthFrac;   /*
                             **  pair of integers to contain integral &
                             **  fract part
                             */
  CHAR szBuffer[MAX_PSIZE];  /*
                             **  a temp buffer to formulate strings for
                             **  insert into lists
                             */
  PSZ  pszb;

  /*
  ** get the custom width set by the user.  make sure it is a valid
  ** width.
  */
  WinQueryDlgItemText( hWnd, EDIT_WIDTH, sizeof( szBuffer ), (PSZ) szBuffer );
  pszb = szBuffer;
  sWidth = cvi( (PB *)&pszb );

  /*
  ** make sure we have a positive number.
  */
  if (!CheckNumeric( hWnd, (PSZ) szBuffer ) || (sWidth <= 0))
  {

    /*
    ** let the user know the width is invalid.
    */
    PostMsgBox( (HMODULE) pcnfData->hmod, (SHORT) 0, IDM_BadWidth, MB_OK |
       MB_ICONEXCLAMATION);

    /*
    ** tell the dialog box to select the entire width field.
    */
    WinSendDlgItemMsg(hWnd, EDIT_WIDTH, EM_SETSEL, (MPARAM)MPFROM2SHORT
       ((SHORT)0, (SHORT)MAX_PSIZE), (MPARAM)0L);

    /*
    ** active the cursor on the width field.
    */
    ShowCursor( WinWindowFromID( hWnd, EDIT_WIDTH ));
    return( FALSE );         /* let 'em know they blew it.                  */
  }

  /*
  ** initialize the fractional parts of the width and height.
  */
  sHeightFrac = sWidthFrac = 0;

  /*
  ** i think that this is finding 1 digit worth of accuracy in the
  ** fractional part of the width, for later use.
  ** !!! this could be cleaned up -kentse.
  */
  if (*szBuffer != ' ')
  {
    if (*pszb == '.')
    {
      pszb++;

      if (*pszb >= '0' && *pszb <= '9')
      {
        sWidthFrac = (SHORT)(*pszb-0x30);
      }
    }
  }

  /*
  ** get the custom height set by the user.  make sure it is a valid
  ** height.
  */
  WinQueryDlgItemText( hWnd, EDIT_HEIGHT, sizeof( szBuffer ), (PSZ) szBuffer );
  pszb = szBuffer;
  sHeight = cvi( (PB *) &pszb );

  /*
  ** make sure we have a positive number.
  */
  if (!CheckNumeric( hWnd, (PSZ) szBuffer ) || (sHeight <= 0))
  {
    /*
    ** let the user know the width is invalid.
    */
    PostMsgBox( (HMODULE)pcnfData->hmod, (SHORT) 0, IDM_BadHeight, MB_OK |
                MB_ICONEXCLAMATION );

    /*
    ** tell the dialog box to select the entire height field.
    */
    WinSendDlgItemMsg( hWnd, EDIT_HEIGHT, EM_SETSEL, (MPARAM) MPFROM2SHORT
                       ((SHORT)0, (SHORT)MAX_PSIZE), (MPARAM)0L);

    /*
    ** active the cursor on the height field.
    */
    ShowCursor( WinWindowFromID( hWnd, EDIT_HEIGHT ) );
    return( FALSE );             /* let 'em know they blew it.                  */
  }

  /*
  ** i think that this is finding 1 digit worth of accuracy in the
  ** fractional part of the height, for later use.
  ** !!! this could be cleaned up -kentse.
  */
  if (*szBuffer != ' ')
  {
    if (*pszb == '.')
    {
      pszb++;

      if (*pszb >= '0' && *pszb <= '9')
      {
        sHeightFrac = (SHORT)(*pszb-0x30);
      }
    }
  }

  /*
  ** adjust the width and height depending on the given units.
  */
  switch (ushUnits)
  {
  case INCHES:
       i = (SHORT) (sWidth * 72 + ((sWidthFrac * 72) / 10));
       j = (SHORT) (sHeight * 72 +((sHeightFrac * 72) / 10));
       break;

  case CMS:
       i = (SHORT)(sWidth *28+((sWidthFrac *28)/10));
       j = (SHORT)(sHeight *28+((sHeightFrac *28)/10));
       break;

  case POINTS :
       i = sWidth;
       j = sHeight;
  }

  /*
  ** save the width and height in our configuration data.
  */
  pcnfData->u.iv.pSourcePaper->shCustomWidth = i;
  pcnfData->u.iv.pSourcePaper->shCustomHeight = j;
  return( TRUE );
}

/***************************************************************************
 *
 * FUNCTION NAME = InitDefineForms
 *
 * DESCRIPTION   = This routine is called to initialize the define forms
 *                 dialog box.
 *
 * INPUT         = HWND     hWnd
 *                 PB  *apResources
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = The address of a DDC, or INVALID_ADDRESS for failure.
 *
 * RETURN-ERROR  = INVALID_ADDRESS
 *
 ****************************************************************************/

VOID InitDefineForms( HWND hWnd, PB *apResources )
{
  SHORT    i, j, k, l, m, cbSize;
  HWND     hWnd1, hWnd2;            /* a temp variable to receive sub handles */
  PCNFDATA pcnfData;                /* pointer to printer configuration data   */
  PDESPPD  pdesPpd;                 /* pointer to printer descriptor segment   */
  CHAR     szBuffer[80];            /* a temp buffer to formulate strings for
                                    **  insert into lists
                                    */
  FORMSTRUCT FormStruct;
  CHAR     szDefPaper[MAX_PSIZE];
  PSZ      pszb;
  MRESULT  mi;
  BOOL     fIsPredefined;

  /*
  ** get pointers to printer configuration data and printer segment info.
  */

  pcnfData = (PCNFDATA) apResources[CNFRES];
  pdesPpd = (PDESPPD) apResources[PPDRES];

  /*
  ** get the subwindow handle of the paper size list box, and
  ** clear all the entries.
  */
  hWnd1 = WinWindowFromID( hWnd, LIST_SIZE );
  WinSendMsg( hWnd1, LM_DELETEALL, (MPARAM) NULL, (MPARAM) NULL);

  /*
  ** read the default paper name into a scratch buffer.
  */
  strcpy( szDefPaper, GetDefaultPageSize(  pdesPpd, apResources[RESBUF] ) );
#if 0
//if (pdesPpd->desPage.ofsDfpgsz != -1)
//{
//  i = *(apResources[RESBUF]+pdesPpd->desPage.ofsDfpgsz);
//
//  if (i < MAX_PSIZE)       /* paper size limited to MAX_PSIZE             */
//  {
//    cbSize = i;
//  }
//  else
//  {
//    cbSize = MAX_PSIZE-1;
//  }
//
//  /*
//  ** copy the name into the buffer.
//  */
//  szNewCopy( (PSZ) szDefPaper, (PSZ)(apResources[RESBUF] +
//             pdesPpd->desPage.ofsDfpgsz+1), (cbSize + 1) );
//  *(szDefPaper+cbSize) = '\0';/* make it NULL terminated.                 */
//}
#endif

  /*
  ** insert all the paper types for the current printer into
  ** the paper size list box.
  */
  fIsPredefined = FALSE;
/*j = pdesPpd->desPage.ofsImgblPgsz; */

  for (i = 0; i < pdesPpd->desPage.iImgpgpairs; i++)
  {
    GetImageableArea( i, (PFORMSTRUCT)&FormStruct, pdesPpd,
                      (PBYTE)apResources[RESBUF] );
    strcpy( szBuffer, FormStruct.FormName );
#if 0
//  k = *(apResources[RESBUF] + j);
//  j++;
//
//  if (k < MAX_PSIZE)       /* paper size limited to MAX_PSIZE             */
//  {
//    cbSize = k;
//  }
//  else
//  {
//    cbSize = MAX_PSIZE-1;
//  }
//  szNewCopy( (CHAR *)szBuffer, (CHAR *)apResources[RESBUF]+j, (cbSize
//             + 1));
//  j += k;
//  *(szBuffer+cbSize) = '\0';/* make it a proper string                    */
//  j += 8;                  /* skip the next 8 bytes which are dimensions  */
#endif
    /*
    **           
    */
#if 0
//  WinSendMsg( hWnd1, LM_INSERTITEM, (MPARAM)LIT_SORTASCENDING, (MPARAM)(PSZ)
//              szBuffer );
#endif
    DisplayTranslationString( hWnd1, szBuffer, LIT_SORTASCENDING );

    /*
    **check whether form name is user defined or predefined
    */
    if (!fIsPredefined)
    {
      if ( ! CompareRealNames( (PSZ)szBuffer,
                               (PSZ)pcnfData->jobProperties.szFormName))
      {
        fIsPredefined = TRUE;
      }
    }
  }

  /*
  ** if the current printer supports custom paper sizes, insert
  ** 'custom' as one of the choices in the paper size list box.
  */
  if (pdesPpd->desPage.fIsVariablePaper == TRUE)
  {
    WinSendMsg( hWnd1, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM)(PSZ)StringTable
       [IDS_Custom-STRING_BASE]);
  }

  /*
  ** search for the default paper size in the list box.  if it is
  ** found, highlight it.
  */
  mi = WinSendMsg( hWnd1, LM_SEARCHSTRING, (MPARAM)(MPFROM2SHORT(0, (SHORT)
                   LIT_FIRST)), (MPARAM)szDefPaper);

  if (mi != (void *)LIT_NONE)
  {
    WinSendMsg( hWnd1, LM_SELECTITEM, (MPARAM)mi, (MPARAM)TRUE);
  }

  /*
  ** get the form size for the current form.
  */
  WinSendMsg( hWnd1, LM_QUERYITEMTEXT, MPFROM2SHORT(mi, MAX_FNAMESIZE), (MPARAM)
              pcnfData->jobProperties.szFormSize);
  /*
  ** disable the custom group box related items.
  */

  WinEnableWindow( WinWindowFromID( hWnd, EDIT_WIDTH ), FALSE);
  WinEnableWindow( WinWindowFromID( hWnd, EDIT_HEIGHT ), FALSE);
  WinEnableWindow( WinWindowFromID( hWnd, TEXT_HEIGHT ), FALSE);
  WinEnableWindow( WinWindowFromID( hWnd, TEXT_WIDTH ), FALSE);
  WinEnableWindow( WinWindowFromID( hWnd, TEXT_UNITS ), FALSE);
  WinEnableWindow( WinWindowFromID( hWnd, GROUP_CUSTOM ), FALSE);

  /*
  ** get the subwindow handle for the units list box.  then clear
  ** out the list box.
  */
  hWnd1 = WinWindowFromID( hWnd, LIST_UNITS );
  WinSendMsg( hWnd1, LM_DELETEALL, (MPARAM) NULL, (MPARAM) NULL );

  /*
  ** set the max character length for the width and height fields to 5.
  */
  WinSendMsg( WinWindowFromID(hWnd, EDIT_WIDTH), EM_SETTEXTLIMIT, (MPARAM) 5L,
             (MPARAM) 0L);
  WinSendMsg( WinWindowFromID(hWnd, EDIT_HEIGHT), EM_SETTEXTLIMIT, (MPARAM) 5L,
              (MPARAM) 0L);

  /*
  ** clear out the form name edit field, and put the cursor there.
  */
  WinSetDlgItemText( hWnd, EDIT_NAME, (PSZ) "" );
  ShowCursor( WinWindowFromID( hWnd, EDIT_NAME) );
  return;
}
/***************************************************************************
 *
 * FUNCTION NAME = AddToIni
 *
 * DESCRIPTION   = if szFormSize is not NULL this routine adds/updates
 *                 a new form mapping pair to os2.ini.
 *                 If szFormSize is NULL it removes the segment.
 *
 * INPUT         = HWND      hWnd
 *                 PSZ       szFormName
 *                 PSZ       szFormSize
 *                 PCNFDATA  pcnfData
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = The address of a DDC, or INVALID_ADDRESS for failure.
 *
 * RETURN-ERROR  = INVALID_ADDRESS
 *
 ****************************************************************************/

BOOL AddToIni (HWND hWnd, PSZ szFormName, PSZ szFormSize, PCNFDATA pcnfData )
{
  SHORT iIndex, jIndex, uSize;
  ULONG ulCount;
  PSZ   pszUserForms = NULL;
  CHAR  szBuffer[MAX_PSIZE];

  /*
  ** check whether szFormName is a valid name or not.
  */
  iIndex = 0;

  while (*(szFormName+iIndex) == ' ')
  {
    iIndex++;
  }

  if (*(szFormName+iIndex) == '\0')
  {
    PostMsgBox( (HMODULE)pcnfData->hmod, (SHORT)0, IDM_BadFormName, MB_OK|
                MB_ICONEXCLAMATION  );
    return( FALSE );
  }

  /*
  ** query how much memory is needed for the formname information.
  */
  if (!PrfQueryProfileSize( HINI_SYSTEMPROFILE, (PSZ) pcnfData->szKeyApp, (PSZ)
       szKeyUserformName, (PULONG)&ulCount))
  {
    ulCount = 0;
  }
  uSize = (SHORT)ulCount+100;

  /*
  ** allocate memory so the form information can be read from
  ** os2sys.ini.
  */
  if ( !( pszUserForms = GplMemoryAlloc ( pProcessHeap, (ULONG)uSize )))
  {
    return( FALSE );
  }

  /*
  ** read in the form name information from os2sys.ini.
  */
  PrfQueryProfileString( HINI_SYSTEMPROFILE, (PSZ)pcnfData->szKeyApp, (PSZ)
                         szKeyUserformName, (PSZ)"", (PSZ)pszUserForms, (ULONG) uSize );

  /*
  ** the form name mappings are in the format
  ** <form name>;<form size>;;<form name>;<form size> ...
  ** search through all the form names looking for the given one.
  */
  iIndex = 0;
  jIndex = -1;

  while ((SHORT)iIndex < (SHORT)(ulCount-1))/* @220 COMPARE MUST BE SIGNED  */
  {
    szDlmCopy((PSZ)szBuffer, (PSZ)(pszUserForms+iIndex), MAX_PSIZE );

    if ( ! CompareRealNames( (PSZ)szBuffer, (PSZ)szFormName ) )
    {
      jIndex = iIndex;

      /*
      ** Skip form name.
      */
      while (*(pszUserForms+jIndex++) != ';');

      /*
      ** Skip form size.
      */
      while (*(pszUserForms+jIndex++) != ';');
      jIndex++;              /* skip second semicolon.                      */

      while (*(pszUserForms+jIndex) != '\0')
      {
        *(pszUserForms+iIndex++) = *(pszUserForms+jIndex++ );
      }
      *(pszUserForms+iIndex) = '\0';/* remove the found entry.              */
    }

    /*
    ** else, skip the form name and size and compare the next form.
    */
    else
    {
      /*
      ** Skip form name.
      */
      while (*(pszUserForms+iIndex++) != ';');

      /*
      ** Skip form size.
      */
      while (*(pszUserForms+iIndex++) != ';');
      iIndex++;              /* skip second semicolon.                      */
    }
  }

  /*
  ** if form size is not NULL then append the new user form mapping
  ** to this buffer.
  */
  if (szFormSize != NULL)
  {
    iIndex = 0;

    /*
    ** make sure string is NULL terminated.
    */
    *(pszUserForms + (SHORT)ulCount) = '\0';

    /*
    ** append string to the buffer.
    */
    while (*(pszUserForms+iIndex) != '\0')
    {
      iIndex++;
    }
    iIndex += NameWithSC( (PSZ) (pszUserForms+iIndex), (PSZ) szFormName );
    iIndex += NameWithSC( (PSZ) (pszUserForms+iIndex), (PSZ) szFormSize );
    *(pszUserForms+iIndex++) = ';';/* the pair terminating semicolon        */
    *(pszUserForms+iIndex) = '\0';

    /*
    ** set jIndex to zero so we won't pop up the dialog box below.
    */
    jIndex = 0;
  }

  /*
  ** write the buffer back out to os2sys.ini.
  */
  PrfWriteProfileString( HINI_SYSTEMPROFILE, (PSZ) pcnfData->szKeyApp, (PSZ)
                         szKeyUserformName, (PSZ) pszUserForms );

  /*
  ** free up the allocated memory.
  */
  GplMemoryFree((PVOID)pszUserForms );
  pszUserForms = NULL;

  /*
  ** jIndex will be -1 iff we are trying to delete a form, but
  ** could not find the form we want to delete.
  */
  if (jIndex == -1)
  {
    PostMsgBox( (HMODULE)pcnfData->hmod, (SHORT)0, IDM_CantDeleteForm, MB_OK|
                MB_ICONEXCLAMATION );
    return( FALSE );
  }
  else
  {
    return( TRUE );
  }
}

/***************************************************************************
 *
 * FUNCTION NAME = SetupProc
 *
 * DESCRIPTION    This routine retrieves the paper list and font list from PPB
 *                Resources and inserts them into the respective list boxes.
 *                This routine also selectively enables the radio buttons for
 *                which bins are provided in the printer selected .
 *
 * INPUT         = HWND      hWnd
 *                 SHORT    uMsg
 *                 MPARAM    mp1
 *                 MPARAM    mp2
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = The address of a DDC, or INVALID_ADDRESS for failure.
 *
 * RETURN-ERROR  = INVALID_ADDRESS
 *
 ****************************************************************************/

ULONG EXPENTRY SetupProc( HWND hWnd, SHORT uMsg, MPARAM mp1, MPARAM mp2 )
{
  SHORT  i, j, k, shItems;
  PB    *apResources;    /*
                             **  list of pointers to printer configuration
                             **  resources
                             */
  PCNFDATA pcnfData;               /* pointer to printer configuration      */
  PDESPPD  pdesPpd;                  /* pointer to printer resources                */
  HWND     hWnd1, hWnd2;               /* A temp variable to get child window handle */
  SHORT    mi;
  SHORT    idTemp;
  CHAR     szBuffer[40];               /* a scratch buffer to read edit fields      */
  CHAR     szPaper[MAX_PSIZE];   /* a scratch buffer to read paper names            */
  PCNFDATA pcnfLocal;        /*
                             **  a local copy of configuration data which is
                             **  transferred to global if OK is pressed
                             */
  PSZ      pszb;
  BOOL     fIsPredefined;
  FORMSTRUCT FormStruct;

  switch (uMsg)
  {
  case WM_COMMAND:

       /*
       **retrieve address of apResources from window words
       */
       apResources = (PB *)WinQueryWindowULong(hWnd, QWL_USER );

       /*
       **  pointer to printer con data
       */
       pcnfData = (PCNFDATA)apResources[CNFRES];

       /*
       **  printer segment info pointer
       */
       pdesPpd = (PDESPPD)apResources[PPDRES];

       /*
       **  pointer to printer local data
       */
       pcnfLocal = (PCNFDATA)apResources[LCLRES];

       /*
       **This switch tells us on which item was mouse clicked
       */
       switch (LOUSHORT( mp1 ))
       {
       /*
       **  user exits the dialog box by pressing button ADD
       */
       case PUSH_ADD:
            WinQueryDlgItemText( hWnd, EDIT_NAME, MAX_PSIZE, (PSZ)
                                 pcnfData->jobProperties.szFormName );

            if ( ! CompareRealNames( (PSZ) StringTable[IDS_Custom-STRING_BASE],
                                     (PSZ)pcnfData->jobProperties.szFormName))
            {
              PostMsgBox( (HMODULE)pcnfData->hmod, (SHORT)0, IDM_CantAddForm,
                 MB_OK | MB_ICONEXCLAMATION );

              /*
              ** activate the cursor on scale field
              */
              ShowCursor( WinWindowFromID( hWnd, EDIT_NAME) );
              break;
            }
            szNewCopy( (PSZ) szBuffer, (PSZ) pcnfData->jobProperties.szFormSize,
                       MAX_PSIZE );

            if ( ! CompareRealNames( (PSZ) StringTable[IDS_Custom-STRING_BASE],
                                     (PSZ)pcnfData->jobProperties.szFormSize))
            {
              /*
              ** read the custom size specification if any specified
              */
              hWnd1 = WinWindowFromID( hWnd, LIST_UNITS );/* get sub window id  */

              /*
              **  get index of selected item
              */
              mi = (SHORT) WinSendMsg( hWnd1, LM_QUERYSELECTION, (MPARAM) 0L,
                                       (MPARAM) 0L );

              /*
              ** whatever the units specified reread the width
              ** and height of custom size
              */
              if (!CustomSize( hWnd, pcnfData, mi ))
              {
                break;
              }

              /*
              ** copy the form size to a scratch buffer and append width
              ** and height into custom i.e. custom(640,780)
              */
              szNewCopy( (PSZ) szBuffer, (PSZ) StringTable[IDS_Custom-STRING_BASE],
                         MAX_PSIZE );
              i = 0;

              while (*(szBuffer+i) != '\0')
              {
                i++;
              }
              *(szBuffer+i++) = '(';
              i += b2a( (PSZ) (szBuffer+i),
                                  pcnfData->u.iv.pSourcePaper->shCustomWidth );
              *(szBuffer+i++) = ',';
              i += b2a( (PSZ) (szBuffer+i),
                                 pcnfData->u.iv.pSourcePaper->shCustomHeight );
              *(szBuffer+i++) = ')';
              *(szBuffer+i) = '\0';/* make it a null terminated string        */
            }

            /*
            **Compare with all the paper types from PPB resource
            */
            fIsPredefined = FALSE;
/********** j = pdesPpd->desPage.ofsImgblPgsz; **/

            for (i = 0; i < pdesPpd->desPage.iImgpgpairs; i++)
            {
              GetImageableArea( i, (PFORMSTRUCT)&FormStruct, pdesPpd,
                                (PBYTE)apResources[RESBUF] );
              strcpy( szPaper, FormStruct.FormName );
#if 0
//            k = *(apResources[RESBUF]+j );
//            j++;
//            szNewCopy( (CHAR *)szPaper, (CHAR *)apResources[RESBUF]+j,
//                       (k+1) );
//            j += k;
//            *(szPaper+k) = '\0';/* make it a proper string                  */
//            j += 8;        /* skip the next 8 bytes which are dimensions  */
#endif
              /*
              **        check whether form name is user defined or predefined
              */
              if (!fIsPredefined)
              {
                if ( ! CompareRealNames( (PSZ) szPaper,
                                      (PSZ)pcnfData->jobProperties.szFormName))
                {
                  fIsPredefined = TRUE;
                }
              }
            }

            /*
            ** add to os2.ini
            */
            if (!fIsPredefined)
            {
              if (!AddToIni(hWnd, (PSZ) pcnfData->jobProperties.szFormName, (PSZ)
                 szBuffer, (PCNFDATA)pcnfData))
              {
                ShowCursor(WinWindowFromID(hWnd, EDIT_NAME) );
                break;
              }
            }
            else
            {
              PostMsgBox( (HMODULE) pcnfData->hmod, (SHORT) 0, IDM_CantAddForm,
                 MB_OK | MB_ICONEXCLAMATION );

              /*
              ** activate cursor on the file name field.
              */
              ShowCursor( WinWindowFromID( hWnd, EDIT_NAME) );
              break;
            }
            WinDismissDlg( hWnd, TRUE );
            break;

        /*
        ** User exits the dialog box by pressing CANCEL.
        */
        case MBID_CANCEL:
             *pcnfData = *(PCNFDATA)pcnfLocal;   /* transfer to local copy          */
             WinDismissDlg(hWnd, TRUE );
             break;
  default:
      break;
  }
  break;

  case WM_CONTROL:
       /*
       **retrieve address of apResources from window words
       */
       apResources = (PB *)WinQueryWindowULong( hWnd, QWL_USER );

       /*
       **  pointer to printer configuration data
       */
       pcnfData = (PCNFDATA)apResources[CNFRES];

       /*
       **  pointer to printer configuration data
       */
       pcnfLocal = (PCNFDATA)apResources[LCLRES];

       /*
       **This switch tells us on which item was mouse clicked
       */
       switch (LOUSHORT(mp1))
       {
       case LIST_SIZE:
            if (HIUSHORT(mp1) == LN_SELECT)
            {
              hWnd1 = WinWindowFromID(hWnd, LIST_SIZE );/* get sub window id   */

              /*
              **  get index of selected item
              */
              mi = (SHORT)WinSendMsg( hWnd1, LM_QUERYSELECTION, (MPARAM) 0L,
                                      (MPARAM)0L );

              /*
              ** Highlight the selected item on which mouse was clicked
              ** and get name of the selected item ,from papers name list,
              ** so that the selected name can instead be displayed.
              */
              WinSendMsg( hWnd1, LM_SELECTITEM, (MPARAM)mi, (MPARAM)TRUE );

              /*
              **  Get the item name
              */
              WinSendMsg( hWnd1, LM_QUERYITEMTEXT, MPFROM2SHORT(mi, MAX_FNAMESIZE),
                          (MPARAM)pcnfData->jobProperties.szFormSize );

              if ( ! CompareRealNames( (PSZ) pcnfData->jobProperties.szFormSize,
                                       (PSZ)StringTable[IDS_Custom-STRING_BASE]))
              {
                /*
                **  enable the customs parameter related group box.
                **  display custom source width and height.
                */
                WinEnableWindow(WinWindowFromID( hWnd, EDIT_WIDTH ), TRUE );
                WinEnableWindow(WinWindowFromID( hWnd, EDIT_HEIGHT ), TRUE );
                WinEnableWindow(WinWindowFromID( hWnd, TEXT_HEIGHT ), TRUE );
                WinEnableWindow(WinWindowFromID( hWnd, TEXT_WIDTH ), TRUE );
                WinEnableWindow(WinWindowFromID( hWnd, TEXT_UNITS ), TRUE );
                WinEnableWindow(WinWindowFromID( hWnd, GROUP_CUSTOM ), TRUE );
                WinSetDlgItemShort(hWnd, EDIT_WIDTH, 0, (BOOL)FALSE );
                WinSetDlgItemShort(hWnd, EDIT_HEIGHT, 0, (BOOL)FALSE );
                hWnd1 = WinWindowFromID( hWnd, LIST_UNITS );

                /*
                **  clear the units list box
                */
                WinSendMsg( hWnd1, LM_DELETEALL, (MPARAM)NULL, (MPARAM)NULL );
                WinSendMsg( hWnd1, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM)(PSZ)
                StringTable[IDS_Inches-STRING_BASE] );
                WinSendMsg( hWnd1, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM)(PSZ)
                StringTable[IDS_Cms-STRING_BASE] );
                WinSendMsg( hWnd1, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM)(PSZ)
                StringTable[IDS_Points-STRING_BASE] );
                mi = 0;      /* display units in inches                     */
                WinSendMsg( hWnd1, LM_SELECTITEM, (MPARAM)mi, (MPARAM)TRUE );
                WinShowCursor( hWnd1, TRUE );
              }
              else
              {
                /*
                **  disable the customs parameter related group box
                */
                WinEnableWindow( WinWindowFromID( hWnd, EDIT_WIDTH ), FALSE );
                WinEnableWindow( WinWindowFromID( hWnd, EDIT_HEIGHT ), FALSE );
                WinEnableWindow( WinWindowFromID( hWnd, TEXT_HEIGHT ), FALSE );
                WinEnableWindow( WinWindowFromID( hWnd, TEXT_WIDTH ), FALSE );
                WinEnableWindow( WinWindowFromID( hWnd, TEXT_UNITS ), FALSE );
                hWnd1 = WinWindowFromID( hWnd, LIST_UNITS );

                /*
                **  clear the units list box
                */
                WinSendMsg( hWnd1, LM_DELETEALL, (MPARAM)NULL, (MPARAM)NULL );
              }
            }
            break;

       case LIST_UNITS:
            if (HIUSHORT(mp1) == LN_SELECT)
            {
              hWnd1 = WinWindowFromID( hWnd, LIST_UNITS );/* get sub window id  */

              /*
              **  get index of selected item
              */
              mi = (SHORT)WinSendMsg( hWnd1, LM_QUERYSELECTION, (MPARAM)0L,
                                      (MPARAM)0L );

              /*
              **        Highlight the selected item on which mouse was clicked
              **        and get name of the selected item ,from papers name list,
              **        so that the selected name can instead be displayed.
              */
              WinSendMsg( hWnd1, LM_SELECTITEM, (MPARAM)mi, (MPARAM)TRUE );
              ShowCursor( WinWindowFromID( hWnd, EDIT_WIDTH) );
            }
            break;

       default:
            break;
       }
       break;

  case WM_INITDLG :
       apResources = (PB *)mp2;
       pcnfData = (PCNFDATA)apResources[CNFRES];

       /*
       **  pointer to printer configuration data
       */
       pcnfLocal = (PCNFDATA)apResources[LCLRES];

       /*
       **store this data address so that it can be retrieved elsewhere
       */
       if (!WinSetWindowULong(hWnd, QWL_USER, (ULONG) (PB *)apResources))
       {
         break;
       }
       *pcnfLocal = *(PCNFDATA)pcnfData;/* transfer to local copy           */

       /*
       **Control comes to this routine before the dialog box is loaded
       **so that dialog box initialisations can be carried out
       */
       /*
       ** Disable the menu item Close and Task_Manager
       */
       hWnd1 = WinWindowFromID( hWnd, FID_SYSMENU );
       WinSendMsg( hWnd1, MM_SETITEMATTR, MPFROM2SHORT(SC_CLOSE, TRUE ),
                   MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED) );
       WinSendMsg( hWnd1, MM_SETITEMATTR, MPFROM2SHORT(SC_TASKMANAGER, TRUE ),
                   MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED) );
       InitDefineForms( hWnd, (PB *)apResources );
       return 1L;            /* to retain the window focus                  */
       break;

  default :
       /*
       **       the action as recommended by PM manuals, no action by Setupproc
       */
         return( (ULONG) WinDefDlgProc(hWnd, uMsg, mp1, mp2) );
  }
  return 0L;
}
