/*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.                                */
/*                                                                           */
/*****************************************************************************/
#pragma  pagesize(55)

/**************************************************************************
 *
 * SOURCE FILE NAME = PROFILE.C
 *
 * DESCRIPTIVE NAME = Interface to plotter specific data
 *
 *
 * VERSION = V2.0
 *
 * DATE      09/18/88
 *
 * DESCRIPTION Functions to access the information stored in the global
 *             data structures defined in PLOTTERS.C and to retireve/store
 *             data in the OS/2 INI file.
 *
 * FUNCTIONS
 *             copy_device_info
 *             copy_pen_option_info
 *             get_defaults
 *             get_device_id
 *             get_printer_name
 *             get_profile
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES  PlotterClass, PlotterDef
 *
 *
 * EXTERNAL FUNCTIONS
 *
*/
#define  INCL_WINCOMMON
#define  INCL_WINSHELLDATA
#include "plotters.h"
#include "error.h"
#include "profile.h"
#include "utils.h"

/*
** Identify section of os2.ini file where our connection data is located
*/

LOCAL char SpoolerPrinter[] = "PM_SPOOLER_PRINTER";

/***************************************************************************
 *
 * FUNCTION NAME = copy_device_info
 *
 * DESCRIPTION   = Return the device characteristics for the requested
 *                 plotter index
 *
 * INPUT         = Plotter     - plotter index
 *
 * OUTPUT        = pDeviceInfo - pointer to DEVICEINFO structure
 *
 * RETURN-NORMAL = NONE
 * RETURN-ERROR  = NONE
 *
 **************************************************************************/

VOID  copy_device_info(PDEVICEINFO pDeviceInfo,SHORT Plotter)
{

  /*
  **     Set up the hardware characteristics for our particular plotter.
  */
  *pDeviceInfo = PlotterClass[Plotter].DeviceInfo;
  return ;
}

/***************************************************************************
 *
 * FUNCTION NAME = copy_pen_option_info
 *
 * DESCRIPTION   = Return the pen option characteristics for the requested
 *                 plotter index
 *
 * INPUT         = Plotter     - plotter index
 *
 * OUTPUT        = pPenOptions - pointer to PENOPTIONS structure
 *
 * RETURN-NORMAL = NONE
 * RETURN-ERROR  = NONE
 *
 **************************************************************************/

VOID  copy_pen_option_info(PPENOPTIONS pPenOptions,SHORT Plotter)
{

  /*
  **   Set up pen information for the type of plotter we are using.
  */
  *pPenOptions = PlotterClass[Plotter].PenOptions;

  return;
}

/***************************************************************************
 *
 * FUNCTION NAME = get_defaults
 *
 * DESCRIPTION   = This function will fill the default setup data for
 *                 the given plotter id.
 *
 * INPUT         = Plotter     - plotter index
 *
 * OUTPUT        = pSetup      - pointer to PROFILEINFO structure
 *
 * RETURN-NORMAL = TRUE if valid plotter ID.
 * RETURN-ERROR  = FALSE if invalid plotter ID.
 *
 **************************************************************************/

BOOL   get_defaults(SHORT Plotter,PPROFILEINFO pSetup)
{
  SHORT Index;
  SHORT CarouselIndex;
  SHORT PenIndex;
  PBYTE pTemp = (PBYTE)pSetup;
  SHORT sCountryCode;
  PDEFPROFILE pDefProfile = &PlotterClass[Plotter].DefProfile;


  if (Plotter < 0 || Plotter >= MAX_PLOTTER_CLASSES)
    return  FALSE;

  /*
  ** Valid - clear the area to zeroes to start with a clean slate
  */
  for (Index = 0; Index < sizeof(PROFILEINFO); Index++)
    pTemp[Index] = 0;

  pSetup->Version         = JOBPROP_VERSION;
  pSetup->CurrentCarousel = 0;
  pSetup->Orientation     = OR_LANDSCAPE;
  pSetup->Roll24          = 24;
  pSetup->Roll36          = 36;
//pSetup->bDraft          = FALSE;
  pSetup->bGECOption      = FALSE;
  pSetup->bPreloaded      = FALSE;

  /*
  ** Setup default Paper size
  */
  pSetup->Size = pDefProfile->sSize;

  /*
  ** Setup default color sort state TRUE=Do color sorting FALSE=Don't
  */
  pSetup->bColorSort = PlotterClass[Plotter].DeviceInfo.fColorSort;

  /*
  ** Setup default paper feed TRUE=Automatic FALSE=Manual
  */
  pSetup->PaperFeed = PlotterClass[Plotter].DeviceInfo.PaperFeedSupport;

  /*
  ** Setup default resolution
  */
  pSetup->lResIndex = pDefProfile->lDefaultResIndex;

  /*
  ** set defaults for the flags
  ** colors
  **     FL_UNCOLLATEDMASK   0x0F       numeric: range 1 .. 16
  **     FL_USEAPPCOLORS     0x10       use application colors
  **     FL_SAVECOLORSORT    0x20       Save the color sorting option
  **     FL_USERDEFINEDFORMS 0x40       Switch interpretation of Size
  **     FL_RASTER           0x80       Rasterize the image
  */
  pSetup->usFlags = 0;
  /*
  ** Setup default use of user defined plotter pen colors or application
  ** colors
  */
  pSetup->usFlags |= (pDefProfile->bUseAppColors ? FL_USEAPPCOLORS : 0);

  /*
  ** Fix for NLS - if CC is USA(1) or Canada(2) or Brazil(55)then use size A
  ** or inches type. For all other countries use A4 or metric type  $787
  **
  */
  sCountryCode = PrfQueryProfileInt(HINI_USERPROFILE, "PM_National",
                                    "iCountry", 1);

  if (sCountryCode == 1 || sCountryCode == 2 || sCountryCode == 55)
  {
    /*
    ** defaults are OK
    */
  }
  else
  {
    /*
    ** if 1 is shifted left by Size we can use it becomes MEDSZ_x values eg.
    ** if ( 1 << pSetup->Size ) == MEDSZ_A or MEDSZ_B or MEDSZ_C or
    ** MEDSZ_D or MEDSZ_E  Then add 5 to Size to convert it to metric.
    ** The quicker way is to see if Size <  A4 index (5) instead of
    ** checking each form
    */
    if (pSetup->Size < 5)       // size less than A4 in table ( plotters.h
    {
      /*
      ** add 5 to size  -  A=>A4, D=>A1, E=>A1
      */
      pSetup->Size += 5;
    }
  }

  /*
  **   Set up the pen colors from the default table
  */
  for (CarouselIndex = 0; CarouselIndex < MAX_CAROUSELS; CarouselIndex++)
  {
    for (PenIndex = 0; PenIndex < MAX_PENS; PenIndex++)
    {
      pSetup->Carousel[CarouselIndex].Pen[PenIndex].Color =
          pDefProfile->uchPenColor[CarouselIndex][PenIndex];
      pSetup->Carousel[CarouselIndex].Pen[PenIndex].Type =
          pDefProfile->uchPenType[CarouselIndex][PenIndex];
    }
  }

  /*
  ** Set carousels to active
  */
  for (CarouselIndex = 0;
       CarouselIndex < pDefProfile->usActiveCarousels;
       CarouselIndex++)
  {
    pSetup->bActiveCarousel[CarouselIndex] = TRUE;
  }

  return  TRUE;
}

/***************************************************************************
 *
 * FUNCTION NAME = get_device_id
 *
 * DESCRIPTION   = Match the given name with the names of devices we
 *                 know about, then return the desired information.
 *
 * INPUT         = pDeviceName - name of plotter
 *
 * OUTPUT        = pClass      - class of name, if found
 *                 pStringId   - string ID of name, if found
 *
 * RETURN-NORMAL = TRUE if match is found.
 * RETURN-ERROR  = FALSE if device name is unknown.
 *
 **************************************************************************/

BOOL  get_device_id(PSZ pDeviceName,PUSHORT pClass,PUSHORT pStringId
)
{
  BOOL bResult = FALSE;
  USHORT usIndex;


  if (pDeviceName)
  {
    for (usIndex = 0; usIndex < usPlotterCount && !bResult; usIndex++)
    {
      if (lstrcmp(PlotterDef[usIndex].pDeviceName, pDeviceName))
      {
        *pClass = PlotterDef[usIndex].usClass;
        *pStringId = PlotterDef[usIndex].usStringId;
        bResult = TRUE;
      }
    }
  }

  return  bResult;
}

/***************************************************************************
 *
 * FUNCTION NAME = get_printer_name
 *
 * DESCRIPTION   = Scan the os2.ini file, section PM_SPOOLER_PRINTER,
 *                 and look for a printer attached to either the queue
 *                 or logical address pointed at by pszLogAddress.  Look
 *                 for the queue name if this is a queued DC.
 *
 *                 Format of os2.ini file is :-
 *                     Device_name;PORT;Driver.Type;Queue;;
 *
 *                 Where device_name is the name in the control Panel
 *                 "Printer Connections" section; PORT is the
 *                 serial/parallel port to which the device is
 *                 connected (e.g.  COM1), Driver.Type is the name of
 *                 the driver (PLOTTERS in our case) and Type is the
 *                 particular type of plotter (e.g.  IBM6180), and
 *                 Queue is the name of the spooler queue associated
 *                 with this device.
 *
 * INPUT         = hmcbHeap        - address of allocated heap
 *                 hAB          - anchor block handle
 *                 DcType       - device context type
 *                 pszLogAddress  - logical printer name
 *
 * OUTPUT        = pPrinter     - name of printer
 *
 *
 * RETURN-NORMAL = TRUE if match is found.
 * RETURN-ERROR  = FALSE if device name is unknown.
 *
 **************************************************************************/

BOOL  get_printer_name(PVOID hmcbHeap, HAB hAB, LONG lDcType,
                                 PSZ pszLogAddress,PSZ pPrinter)
{
  BOOL  bResult = FALSE;
  CHAR  szPrinterNames[256];
  SHORT LogAddrSize = 0;


  if (pszLogAddress)
  {
    LogAddrSize = lstrlen(pszLogAddress);
  }

  /*
  **    Get the names of entries in spooler's printer part of os2.ini.
  */
  if (PrfQueryProfileString((HINI)HINI_SYSTEMPROFILE, SpoolerPrinter, (PSZ)NULL,
                            (PSZ)NULL, szPrinterNames, 255) < 255)
  {
    PBYTE pNames = (PBYTE)szPrinterNames;

    /*
    **      Get each entry of the printer section looking for an entry that
    **  matches pszLogAddress.
    */
    while (*pNames && !bResult)
    {
      ULONG ulSize = 0L;
      PSZ pProfile = 0L;


      if (PrfQueryProfileSize((HINI)HINI_SYSTEMPROFILE, SpoolerPrinter,
                                                        pNames, &ulSize) &&
                               (pProfile = (PSZ)GplMemoryAlloc (hmcbHeap,
                                                                ulSize+1)) &&
                                (PrfQueryProfileString((HINI)HINI_SYSTEMPROFILE,
                                                       SpoolerPrinter,
                                                       pNames, (PSZ)NULL,
                                                       pProfile,
                                                       ulSize) == ulSize))
      {
        PBYTE pTemp = (PBYTE)pProfile;
        SHORT Count = 0;


        if (lDcType == OD_QUEUED)
        {

          /*
          **   If queued,  we need to match the plotter on the
          **  queue name (between 2nd and 3rd `;') in the entry.
          */
          while (*pTemp && Count < 2)
          {

            if (*pTemp == ';')
              ++Count;
            ++pTemp;
          }

          if (Count == 2)
          {
            do
            {
              if (lstrncmp(pTemp, pszLogAddress, LogAddrSize))
              {

                 /*
                 ** Strings match - check we have not
                 ** matched ** a substring by looking for a
                 ** terminator.
                 */
                if (*(pTemp+LogAddrSize) == ',' || *(pTemp+LogAddrSize) == ';' )
                {
                  lstrcpy(pPrinter, pNames);
                  bResult = TRUE;
                  break;
                }
              }

              while (*pTemp != ',' && *pTemp != ';')
              {
                ++pTemp;
              }
            }

            while (*pTemp++ == ',');
          }
        }

        else
        {

          /*    Not queued,  meaning direct.  Hence we match
          **  on the initial entry of the section.
          */
          if (lstrncmp(pszLogAddress, pProfile, LogAddrSize))
          {
            /*
            **  Check for substring match
            */
            if (*(pProfile+LogAddrSize) == ',' ||
                *(pProfile+LogAddrSize) == ';')
            {
              lstrcpy(pPrinter, pNames);
              bResult = TRUE;
            }
          }
        }
      }

      if (pProfile)
        if (GplMemoryFree ((PVOID)pProfile))
          pProfile = (PSZ)NULL;

      pNames += lstrlen(pNames)+1;
    }
  }

  return (bResult);
}

/***************************************************************************
 *
 * FUNCTION NAME = get_profile
 *
 * DESCRIPTION   = Look for the entry pDeviceName.pPrinter in our
 *                 private section of the os2sys.ini file.  This
 *                 contains initialization data for the particular
 *                 type of plotter we are using.  A typical name would
 *                 be "IBM6180.PLOTTER1".
 *
 * INPUT         = hmcbHeap        - address of allocated heap
 *                 pszDriverName  - driver name
 *                 pDeviceName  - device name
 *                 pPrinter     - logical printer name
 *
 * OUTPUT        = pSetup       - returned plotter profile information
 *
 *
 * RETURN-NORMAL = TRUE if match is found.
 * RETURN-ERROR  = FALSE if device name is unknown.
 *
 **************************************************************************/

BOOL  get_profile(PVOID hmcbHeap,PSZ pszDriverName,PSZ pszDeviceName,
                            PSZ pszPrinter,PPROFILEINFO pSetup)
{
  BOOL bResult = FALSE;
  CHAR KeyName[MAXKEYSIZE+9];
  CHAR AppName[MAXAPPSIZE];
  ULONG ProfileSize = (ULONG)sizeof(PROFILEINFO);/* made ulong instead of
                                                    ushort       */

  /*
  ** build old key name
  */
  lstrcpy(KeyName, pszDeviceName);
  lstrcpy(KeyName+lstrlen(KeyName), (PSZ)".");
  lstrcpy(KeyName+lstrlen(KeyName), pszPrinter);

  /*
  ** build new app name
  */
  lstrcpy(AppName, PM_DD);              /* copy PM_DD_                       */
  lstrcpy(AppName+lstrlen(AppName),
          pszPrinter);                   /* copy printer name                 */
  lstrcpy(AppName+lstrlen(AppName),
          ",");                        /* copy ","                          */
  lstrcpy(AppName+lstrlen(AppName),
          APP_NAME);                   /* copy driver name ("PLOTTERS")     */
  lstrcpy(AppName+lstrlen(AppName),
          ".");                        /* copy "."                          */
  lstrcpy(AppName+lstrlen(AppName),
          pszDeviceName);              /* copy device name                  */
  bResult = PrfQueryProfileData((HINI)HINI_SYSTEMPROFILE, APP_NAME,
                                KeyName, pSetup, &ProfileSize);

  if (bResult)                         /* query was successful              */
  {
    /*
    ** Good only if the size is correct,  and version number is same
    */
    if (ProfileSize == sizeof(PROFILEINFO) &&
        pSetup->Version == JOBPROP_VERSION  )                        // @MJH3
    {
      /*
      ** since query was successful,
      ** try to write it out in the new format
      */
      bResult = PrfWriteProfileData((HINI)HINI_SYSTEMPROFILE,
                                    (PSZ)AppName,
                                    PRINTER_INFO,
                                    pSetup,
                                    (ULONG)sizeof(PROFILEINFO));

      /*
      ** if write was successful, delete the old format
      */
      if (bResult)
      {
        (void)PrfWriteProfileData((HINI)HINI_SYSTEMPROFILE, APP_NAME,
                                  KeyName, NULL, (ULONG)NULL);
      }
    }
    else
      bResult = FALSE;                 /* return error                      */
  }
  else
  {
    bResult = PrfQueryProfileData((HINI)HINI_SYSTEMPROFILE, (PSZ)AppName,
                                  PRINTER_INFO, pSetup, &ProfileSize);
  }

  return  bResult;
}

