/*DDK*************************************************************************/
/*                                                                           */
/* 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.                                */
/*                                                                           */
/*****************************************************************************/
#ifdef S3
#define  MAXCHARLEN   256

#define  INCL_DOSFILEMGR
#define  INCL_DOSMEMMGR
#define  INCL_DOSMISC

#define INCL_GPIBITMAPS
#define INCL_GPIDISPPRF
#include <eddinclt.h>
#include "edddtypt.h"
#include "eddesres.h"

BOOL    fNeedExtraModeSwitch;

extern PSCREENRESOLUTION asrScreenResolution;
extern USHORT            usNumScreenResolutions;
#ifdef   BPP24
extern DDTType           DDT;
#endif

ULONG ulFilePos, ulFileSize;

PVOID MyAlloc(HFILE hf)
{
   FILESTATUS3  fib;
   ULONG        ulcbread;
   PVOID        pbuf;

   if(!DosQueryFileInfo(hf, FIL_STANDARD, &fib, sizeof(FILESTATUS3)))
   {
      if(!DosAllocMem(&pbuf, fib.cbFile, fALLOC))
      {
         if(!DosRead(hf, pbuf, fib.cbFile, &ulcbread))
         {
            ulFileSize = ulcbread;
            ulFilePos  = 0;
            return(pbuf);
         }
      }
   }

   return(NULL);
}

int MyGetString(PSZ pszStr, ULONG ulsize, PPVOID ppbuf)
{
   ULONG      cnt;

   if(ulFilePos >= ulFileSize) return(0);

   for (cnt=0;cnt < ulsize;cnt++)
   {
      if (((PSZ)*ppbuf)[cnt] == 0x0a)
      {
         pszStr[cnt] = 0;
         (*((PULONG)ppbuf)) += cnt+1;
         ulFilePos += cnt+1;
         break;
      }
      else
      {
         if(ulFilePos + cnt > ulFileSize) return(0);
         pszStr[cnt] = ((PSZ)*ppbuf)[cnt];
      }
   }

   return (1);
}

ULONG Myatoi(PSZ psz)
{

  PSZ    p1;
  ULONG  ulvalue = 0;

  for(p1 = psz; *p1 == 0x20; p1++);   /* Strip leading blanks */

  for(;*p1>='0' && *p1<='9';p1++)     /* Convert ASCII to integer */
  {
     ulvalue = ulvalue * 10;
     ulvalue += *p1 - '0';
  }

  return(ulvalue);
}

int MySscanf(PSZ pszBuffer, PULONG pulid)
{
   PSZ        p1;

   for (p1=pszBuffer;*p1 != '=';p1++);
   *pulid = Myatoi(&p1[1]);
   return(1);

}

//---------------------------------------------------------------------
// MySkipBlanks
//
// Returns a pointer to the first non-blank character in the string.
// Blank characters are defined as spaces, tabs, or the C style comment
// delimiters used in the .PMI file.
//---------------------------------------------------------------------
PSZ MySkipBlanks(PSZ pszBuffer)
{
    PSZ pStr;

    for (pStr=pszBuffer; *pStr != NULL; pStr++)
    {
        if ((*pStr != ' ' ) &&
            (*pStr != '/' ) &&
            (*pStr != '*' ) &&
            (*pStr != '\t'))
            break;
    }
    return(pStr);
}

//---------------------------------------------------------------------
// MyStrNCmp
//
// Compares the first N characters in both strings.  If all characters
// are equal, returns TRUE.  Otherwise, returns FALSE.  Note: No special
// check are provided to ensure either or both strings ends prematurely.
//---------------------------------------------------------------------
BOOL MyStrNCmp(PSZ str1, PSZ str2, USHORT cnt)
{
    USHORT i;

    for (i=0; i<cnt; i++)
    {
        if (str1[i] != str2[i])
            return(FALSE);
    }
    return(TRUE);
}

HFILE Myfopen(PSZ pszFilename)
{
   HFILE   hfile;
   ULONG   ulact;
   ULONG   rc;

   rc = DosOpen(pszFilename, &hfile, &ulact, 0L, 0L, 1L, 0x40L, NULL);
   return (rc ? (HFILE)0 : hfile);
}

VOID SetObtainableModes(VOID)
{
   ULONG      ulDrive;
   CHAR       pszPMIFileName[20] = "#:\\OS2\\SVGADATA.PMI";
   HFILE      hfpmi;
   ULONG      cnt;
   PVOID      pBuf;
   PSZ        pNonBlank;
   char       pszPMIStr[MAXCHARLEN];
   ULONG      ul_xres, ul_yres, ul_clr, ul_planes;

   #ifdef   BPP24
   DDT.fScreenFlags |= USE_ATTDAC;
   #endif

   fNeedExtraModeSwitch = FALSE;

   /* Search for the correct PMI File           */
   /*   We will append the system boot drive    */
   /*   to the OS2 dir and try to open the      */
   /*   file.                                   */

   DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulDrive, sizeof(ULONG));
   pszPMIFileName[0] = (UCHAR)(( (ULONG)'A' + ulDrive ) - 1);

   /* Open and parse for a match                            */
   /*   Search will be base on the [comment] key word in    */
   /*   the appropriate pmi file                            */

   if((hfpmi = Myfopen(pszPMIFileName)) && (pBuf = MyAlloc(hfpmi)))
   {

      while (MyGetString(pszPMIStr, MAXCHARLEN, &pBuf))
      {
         if (MyStrNCmp(pszPMIStr,"[ModeInfo]",10))
         {
            MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);     /* Mode Attributes      */
            MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);     /* Bytes Per Scan Line  */
            MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);     /* X Resolution         */
            MySscanf(pszPMIStr, &ul_xres);
            MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);     /* Y Resolution         */
            MySscanf(pszPMIStr, &ul_yres);
            MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);     /* Text Rows            */
            MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);     /* Bits Per Pixel       */
            MySscanf(pszPMIStr, &ul_clr);
            ul_clr = 1 << ul_clr;                          /* Convert BPP to #clrs */
            MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);     /* Number of Planes     */
            MySscanf(pszPMIStr, &ul_planes);

            for(cnt=0;cnt<usNumScreenResolutions;cnt++)
            {
               if ( asrScreenResolution[cnt].width  == ul_xres   &&
                    asrScreenResolution[cnt].height == ul_yres   &&
                    asrScreenResolution[cnt].colors == ul_clr    &&
                    asrScreenResolution[cnt].planes == ul_planes)
               {
                  asrScreenResolution[cnt].floptions |= DSP_RESOLUTION_OBTAINABLE;
               }
            }

         }
         else if (MyStrNCmp(pszPMIStr,"[AdapterType]",13))
              {
                  MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);
                  MyGetString(pszPMIStr, MAXCHARLEN, &pBuf);

                  //---------------------------------------------------
                  // Although in most cases we can skip the extra mode
                  // set during death, we make a special case for the
                  // Lacuna machines whose BIOS doesn't deal with it
                  // properly.  We originally took out the extra mode
                  // switch after receiving complaint of monitors
                  // getting 'cooked' in Europe.  @RCW
                  //---------------------------------------------------
                  pNonBlank = MySkipBlanks(pszPMIStr);
                  if (MyStrNCmp(pNonBlank,"Special Case Mode Assist",24))
                  {
                      fNeedExtraModeSwitch = TRUE;
                  }

              }
              else
              {
                  //---------------------------------------------------
                  // Fetch the DAC type to determine what method of
                  // DAC interface we'll use and to determine if we
                  // can use 256 grey scales rather than 64.
                  //---------------------------------------------------
                  pNonBlank = MySkipBlanks(pszPMIStr);

                  if (MyStrNCmp(pNonBlank,"HI-COLOR DAC by ",16))
                  {
                      pNonBlank += 16;

                      if (MyStrNCmp(pNonBlank,"Music",5))
                          DDT.fScreenFlags &= ~USE_ATTDAC;

                      else if (MyStrNCmp(pNonBlank,"Brook",5))
                               DDT.fScreenFlags |= (USE_BROOKDAC | USE_8BIT_DAC);

                           else if (MyStrNCmp(pNonBlank,"AT&T",4))
                                    DDT.fScreenFlags |= USE_8BIT_DAC;
                  }

              }

      } // End While

      DosFreeMem(pBuf);
      DosClose(hfpmi);
   }

   return;
}

#endif
