First draft of a simple application to read a bitmap from a file in QSPI memory, and display it on the LPC4088 using the easyGUI library.

Dependencies:   DMBasicGUI DMSupport

easyGUIFixed/GuiComponents.h

Committer:
jmitc91516
Date:
2017-07-28
Revision:
0:6db0d96b351d

File content as of revision 0:6db0d96b351d:

/* ************************************************************************ */
/*                                                                          */
/*                     (C)2004-2015 IBIS Solutions ApS                      */
/*                            sales@easyGUI.com                             */
/*                             www.easyGUI.com                              */
/*                                                                          */
/*                               v6.0.9.005                                 */
/*                                                                          */
/*     GuiLib.c include file - do NOT reference it in your linker setup     */
/*                                                                          */
/* ************************************************************************ */

//------------------------------------------------------------------------------
void GuiLib_ClearPositionCallbacks(void)
{
  GuiConst_INT16U I;

  for (I = 0; I < GuiConst_POSCALLBACK_CNT; I++)
    sgl.PosCallbacks[I].InUse = 0;
}

//------------------------------------------------------------------------------
void GuiLib_SetPositionCallbackFunc(
   GuiConst_INT16U IndexNo,
   void (*PosCallbackFunc) (GuiConst_INT16U IndexNo,
                            GuiConst_INT16S X,
                            GuiConst_INT16S Y))
{
  GuiConst_INT32S I, J;

  J = -1;
  for (I = 0; I < GuiConst_POSCALLBACK_CNT; I++)
    if (sgl.PosCallbacks[I].IndexNo == IndexNo)
    {
      J = I;
      break;
    }
  if (J == -1)
    for (I = 0; I < GuiConst_POSCALLBACK_CNT; I++)
      if (!sgl.PosCallbacks[I].InUse)
      {
        J = I;
        break;
      }

  if (J >= 0)
  {
    sgl.PosCallbacks[J].InUse = 1;
    sgl.PosCallbacks[J].PosCallbackFunc = PosCallbackFunc;
    sgl.PosCallbacks[J].IndexNo = IndexNo;
  }
}

#ifdef GuiConst_CURSOR_SUPPORT_ON
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static void DrawCursorItem(
   GuiConst_INT8U CursorVisible)
{
#ifndef GuiConst_CURSOR_FIELDS_OFF
  GuiConst_INT16S RemCursorFieldNo, I;
  PrefixLocate ItemMemory     RemMemory;
  PrefixLocate ItemMemory  *PrefixLocate CursorMemory;
  PrefixLocate GuiLib_ItemRec *CursorItem;

  if (sgl.CursorInUse && (GuiLib_ActiveCursorFieldNo >= 0))
  {
    I = -1;
    memcpy(&RemMemory, &sgl.Memory, sizeof(ItemMemory));
    while ((I = AutoRedraw_GetCursor(GuiLib_ActiveCursorFieldNo, I)) != -1)
    {
      CursorItem = AutoRedraw_GetItem(I);
      CursorMemory = AutoRedraw_GetItemMemory(I);

      if ((CursorItem == NULL) || (CursorMemory == NULL))
        return;

      memcpy(&sgl.CurItem, CursorItem, sizeof(GuiLib_ItemRec));
      memcpy(&sgl.Memory, CursorMemory, sizeof(ItemMemory));


  #ifdef GuiConst_ITEM_SCROLLBOX_INUSE
      if ((sgl.CurItem.TextPar[0].BitFlags & GuiLib_BITFLAG_FIELDSCROLLBOX) &&
          (sgl.ScrollBoxesAry[sgl.CurItem.CursorScrollBoxIndex].ScrollLineDataFunc != 0))
        sgl.ScrollBoxesAry[sgl.CurItem.CursorScrollBoxIndex].ScrollLineDataFunc(
           sgl.ScrollBoxesAry[sgl.CurItem.CursorScrollBoxIndex].MarkerStartLine[0]);
  #endif // GuiConst_ITEM_SCROLLBOX_INUSE

      if (!CursorVisible)
      {
        RemCursorFieldNo = GuiLib_ActiveCursorFieldNo;
        GuiLib_ActiveCursorFieldNo = -1;
      }
      else
        RemCursorFieldNo = 0;

      sgl.SwapColors = 0;
  #ifdef GuiConst_ITEM_SCROLLBOX_INUSE
      if (sgl.CurItem.TextPar[0].BitFlags & GuiLib_BITFLAG_FIELDSCROLLBOX)
        ScrollBox_DrawScrollLine(sgl.CurItem.CursorScrollBoxIndex,
           sgl.ScrollBoxesAry[sgl.CurItem.CursorScrollBoxIndex].MarkerStartLine[0]);
      else
  #endif // GuiConst_ITEM_SCROLLBOX_INUSE
      {
  #ifdef GuiConst_BITMAP_SUPPORT_ON
        UpdateBackgroundBitmap();
  #endif

        DrawItem(GuiLib_COL_INVERT_IF_CURSOR);
      }

      if (!CursorVisible)
        GuiLib_ActiveCursorFieldNo = RemCursorFieldNo;
    }
    memcpy(&sgl.Memory, &RemMemory, sizeof(ItemMemory));
  }
  #else // GuiConst_CURSOR_FIELDS_OFF
  CursorVisible = 0;
  #endif // GuiConst_CURSOR_FIELDS_OFF
}

//------------------------------------------------------------------------------
void GuiLib_Cursor_Hide(void)
{
#ifndef GuiConst_CURSOR_FIELDS_OFF
  GuiDisplay_Lock();
  DrawCursorItem(0);
  GuiDisplay_Unlock();
  GuiLib_ActiveCursorFieldNo = -1;
#endif // GuiConst_CURSOR_FIELDS_OFF
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_IsCursorFieldInUse(
   GuiConst_INT16S AskCursorFieldNo)
{
#ifndef GuiConst_CURSOR_FIELDS_OFF
  if (AskCursorFieldNo >= 0)
  {
    if (AutoRedraw_GetCursor(AskCursorFieldNo, -1) != -1)
      return 1;
  }

  return 0;
#else // GuiConst_CURSOR_FIELDS_OFF
  return 0;
#endif // GuiConst_CURSOR_FIELDS_OFF
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Cursor_Select(
   GuiConst_INT16S NewCursorFieldNo)
{
#ifndef GuiConst_CURSOR_FIELDS_OFF
  if (NewCursorFieldNo == -1)
  {
    GuiLib_Cursor_Hide();
    return 0;
  }
  else if (NewCursorFieldNo >= 0)
  {
    if (AutoRedraw_GetCursor(NewCursorFieldNo, -1) != -1)
    {
      GuiDisplay_Lock();

      DrawCursorItem(0);
      GuiLib_ActiveCursorFieldNo = NewCursorFieldNo;
      DrawCursorItem(1);

      GuiDisplay_Unlock();

      return 1;
    }
  }

  return 0;
#else
  NewCursorFieldNo = 0;
  return 0;
#endif
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Cursor_Down(void)
{
#ifndef GuiConst_CURSOR_FIELDS_OFF
  GuiConst_INT16S NewCursorFieldNo, Index;

  Index = AutoRedraw_GetNextCursor(GuiLib_ActiveCursorFieldNo);

  NewCursorFieldNo = AutoRedraw_GetCursorNumber(Index);

#ifdef GuiConst_CURSOR_MODE_WRAP_AROUND
  if ((NewCursorFieldNo == GuiLib_ActiveCursorFieldNo)
   || (Index == -1))
    return GuiLib_Cursor_Home();
#else
  if (Index == -1)
    return 0;
#endif

  GuiLib_Cursor_Select(NewCursorFieldNo);

  return 1;
#else
  return 0;
#endif
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Cursor_Up(void)
{
#ifndef GuiConst_CURSOR_FIELDS_OFF
  GuiConst_INT16S NewCursorFieldNo, Index;

  Index = AutoRedraw_GetPrevCursor(GuiLib_ActiveCursorFieldNo);

  NewCursorFieldNo = AutoRedraw_GetCursorNumber(Index);

#ifdef GuiConst_CURSOR_MODE_WRAP_AROUND
  if ((NewCursorFieldNo == GuiLib_ActiveCursorFieldNo)
   || (Index == -1))
    return GuiLib_Cursor_End();
#else
  if (Index == -1)
    return 0;
#endif

  GuiLib_Cursor_Select(NewCursorFieldNo);

  return 1;
#else
  return 0;
#endif

}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Cursor_Home(void)
{
#ifndef GuiConst_CURSOR_FIELDS_OFF
  GuiConst_INT16S NewCursorFieldNo, Index;

  Index = AutoRedraw_GetFirstCursor();

  NewCursorFieldNo = AutoRedraw_GetCursorNumber(Index);

  if (NewCursorFieldNo == GuiLib_ActiveCursorFieldNo)
    return 0;

  GuiLib_Cursor_Select(NewCursorFieldNo);

  return 1;
#else
  return 0;
#endif
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Cursor_End(void)
{
#ifndef GuiConst_CURSOR_FIELDS_OFF
  GuiConst_INT16S NewCursorFieldNo, Index;

  Index = AutoRedraw_GetLastCursor();

  NewCursorFieldNo = AutoRedraw_GetCursorNumber(Index);

  if (NewCursorFieldNo == GuiLib_ActiveCursorFieldNo)
    return 0;

  GuiLib_Cursor_Select(NewCursorFieldNo);

  return 1;
#else
  return 0;
#endif
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#endif // GuiConst_CURSOR_SUPPORT_ON

#ifdef GuiConst_BLINK_SUPPORT_ON
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static void BlinkBox(void)
{
  if ((sgl.BlinkBoxRate) && (sgl.DisplayWriting))
    GuiLib_InvertBox(sgl.BlinkBoxX1, sgl.BlinkBoxY1, sgl.BlinkBoxX2, sgl.BlinkBoxY2);
  sgl.BlinkBoxInverted = !sgl.BlinkBoxInverted;
}

//------------------------------------------------------------------------------
void GuiLib_BlinkBoxStart(
   GuiConst_INT16S X1,
   GuiConst_INT16S Y1,
   GuiConst_INT16S X2,
   GuiConst_INT16S Y2,
   GuiConst_INT16S Rate)
{
  GuiLib_BlinkBoxStop();
  sgl.BlinkBoxX1 = X1;
  sgl.BlinkBoxY1 = Y1;
  sgl.BlinkBoxX2 = X2;
  sgl.BlinkBoxY2 = Y2;
  if (Rate < 1)
    sgl.BlinkBoxRate = 1;
  else
    sgl.BlinkBoxRate = Rate;
  sgl.BlinkBoxState = sgl.BlinkBoxRate;
  sgl.BlinkBoxInverted = 0;
  BlinkBox();
}

//------------------------------------------------------------------------------
void GuiLib_BlinkBoxStop(void)
{
#ifndef GuiConst_BLINK_FIELDS_OFF
  GuiConst_INT16U I;
#endif

  if (sgl.BlinkBoxRate && sgl.BlinkBoxInverted)
    BlinkBox();
  sgl.BlinkBoxRate = 0;

#ifndef GuiConst_BLINK_FIELDS_OFF
  for (I = 0; I < GuiConst_BLINK_FIELDS_MAX; I++)
    if (sgl.BlinkTextItems[I].InUse && sgl.BlinkTextItems[I].Active)
      GuiLib_BlinkBoxMarkedItemStop(I);
#endif
}

//------------------------------------------------------------------------------
void GuiLib_BlinkBoxMarkedItem(
   GuiConst_INT16U BlinkFieldNo,
   GuiConst_INT16U CharNo,
   GuiConst_INT16S Rate)
{
#ifndef GuiConst_BLINK_FIELDS_OFF
  GuiConst_INT16S TextXOfs[GuiConst_MAX_TEXT_LEN + 2];
  TextParRec TempTextPar;
  GuiConst_INT8U TempPs;
  GuiConst_INT16U CharCnt;
  GuiConst_INT16U TempTextLength;
  GuiConst_INT8U TempFormatFieldWidth;
  GuiConst_INT8U TempFormatDecimals;
  GuiConst_INT8U TempFormatAlignment;
  GuiConst_INT8U TempFormatFormat;
  #ifdef GuiConst_REMOTE_FONT_DATA
  GuiConst_INT32U PrefixRom TempOfs;
  GuiConst_INT8U CharHeader[GuiLib_CHR_LINECTRL_OFS];
  #else // GuiConst_REMOTE_FONT_DATA
  GuiConst_INT8U PrefixRom * TempPtr;
  #endif // GuiConst_REMOTE_FONT_DATA
  #ifdef GuiConst_ITEM_TEXTBLOCK_INUSE
  GuiConst_INT8U CharHeader1[GuiLib_CHR_LINECTRL_OFS];
  GuiConst_INT8U CharHeader2[GuiLib_CHR_LINECTRL_OFS];
  GuiConst_INT16S TextCharLineStart[GuiConst_MAX_PARAGRAPH_LINE_CNT];
  GuiConst_INT16S TextCharLineEnd[GuiConst_MAX_PARAGRAPH_LINE_CNT];
  GuiConst_INT16S M;
  GuiConst_INT16S LineCnt;
  GuiConst_INT16S LineCnt2;
  GuiConst_INT16S LineLen;
  GuiConst_INT16S XStart, XEnd;
  GuiConst_INT16S P2;
  #endif // GuiConst_ITEM_TEXTBLOCK_INUSE
  GuiConst_INT16S N;
#ifndef GuiConst_CHARMODE_ANSI
  GuiConst_INT16S P1;
#endif
  GuiConst_TEXT PrefixGeneric *CharPtr;
  GuiConst_INT32S VarValue;
  GuiConst_INT16S TextPixelLen;

  if ((BlinkFieldNo >= GuiConst_BLINK_FIELDS_MAX) ||
      !sgl.BlinkTextItems[BlinkFieldNo].InUse)
    return;

  if (sgl.BlinkTextItems[BlinkFieldNo].Active &&
      sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate &&
      sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted)
  {
    if (sgl.DisplayWriting)
    {
      GuiLib_InvertBox(sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1,
                       sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1,
                       sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2,
                       sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY2);
      sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted =
         !sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted;
      sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxLast =
         sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted;
    }
  }

  sgl.BlinkTextItems[BlinkFieldNo].Active = 0;
  sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate = 0;

  if ((BlinkFieldNo < GuiConst_BLINK_FIELDS_MAX) &&
       sgl.BlinkTextItems[BlinkFieldNo].InUse)
  {
    sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 = sgl.BlinkTextItems[BlinkFieldNo].X1;
    sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2 = sgl.BlinkTextItems[BlinkFieldNo].X2;
    sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1 = sgl.BlinkTextItems[BlinkFieldNo].Y1;
    sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY2 = sgl.BlinkTextItems[BlinkFieldNo].Y2;

    if (sgl.BlinkTextItems[BlinkFieldNo].InUse)
    {
      TempTextPar = sgl.CurItem.TextPar[0];
      TempTextLength = sgl.CurItem.TextLength[0];
      TempFormatFieldWidth = sgl.CurItem.FormatFieldWidth;
      TempFormatDecimals = sgl.CurItem.FormatDecimals;
      TempFormatAlignment = sgl.CurItem.FormatAlignment;
      TempFormatFormat = sgl.CurItem.FormatFormat;

      sgl.CurItem.FormatFieldWidth = sgl.BlinkTextItems[BlinkFieldNo].FormatFieldWidth;
      sgl.CurItem.FormatDecimals = sgl.BlinkTextItems[BlinkFieldNo].FormatDecimals;
      sgl.CurItem.FormatAlignment = sgl.BlinkTextItems[BlinkFieldNo].FormatAlignment;
      sgl.CurItem.FormatFormat = sgl.BlinkTextItems[BlinkFieldNo].FormatFormat;
      sgl.CurItem.TextPar[0] = sgl.BlinkTextItems[BlinkFieldNo].TextPar;
      CharCnt = sgl.BlinkTextItems[BlinkFieldNo].CharCnt;
      sgl.CurItem.TextLength[0] = CharCnt;

      SetCurFont(sgl.BlinkTextItems[BlinkFieldNo].TextPar.FontIndex);

      if ((sgl.BlinkTextItems[BlinkFieldNo].ItemType == GuiLib_ITEM_TEXT) ||
          (sgl.BlinkTextItems[BlinkFieldNo].ItemType == GuiLib_ITEM_TEXTBLOCK))
      {
#ifdef GuiConst_CHARMODE_UNICODE
        ExtractUnicodeString(
           (GuiConst_INT8U PrefixRom *)sgl.BlinkTextItems[BlinkFieldNo].TextPtr,
            sgl.CurItem.TextLength[0]);
  #ifdef GuiConst_ARAB_CHARS_INUSE
        if (sgl.BlinkTextItems[BlinkFieldNo].TextPar.BitFlags &
            GuiLib_BITFLAG_REVERSEWRITING)
        {
          CharCnt = ArabicCorrection(
             sgl.UnicodeTextBuf, CharCnt,
             (sgl.BlinkTextItems[BlinkFieldNo].TextPar.BitFlags &
              GuiLib_BITFLAG_REVERSEWRITING) > 0);
        }
  #endif // GuiConst_ARAB_CHARS_INUSE
#endif // GuiConst_CHARMODE_UNICODE

#ifdef GuiConst_CHARMODE_UNICODE
        CharPtr = (GuiConst_TEXT PrefixGeneric *)sgl.UnicodeTextBuf;
#else // GuiConst_CHARMODE_UNICODE
        CharPtr = (GuiConst_TEXT PrefixRom *)sgl.BlinkTextItems[BlinkFieldNo].TextPtr;
#endif // GuiConst_CHARMODE_UNICODE
        PrepareText(CharPtr,CharCnt,0);
      }
      else
      {
#ifdef GuiConst_DISP_VAR_NOW
        displayVarNow = 1;
#endif
        if (sgl.BlinkTextItems[BlinkFieldNo].VarType == GuiLib_VAR_STRING)
        {
          CharPtr = (GuiConst_TEXT PrefixGeneric *)sgl.BlinkTextItems[BlinkFieldNo].TextPtr;
#ifdef GuiConst_CHARMODE_ANSI
          CharCnt = strlen(CharPtr);
#else
#ifdef GuiConst_CODEVISION_COMPILER
          CharCnt = GuiLib_UnicodeStrLen((GuiConst_TEXT*)CharPtr);
#else // GuiConst_CODEVISION_COMPILER
          CharCnt = GuiLib_UnicodeStrLen(CharPtr);
#endif // GuiConst_CODEVISION_COMPILER
#endif // GuiConst_CHARMODE_ANSI
        }
        else
        {
          VarValue = ReadVar(sgl.BlinkTextItems[BlinkFieldNo].TextPtr,
                             sgl.BlinkTextItems[BlinkFieldNo].VarType);

          CharCnt =
             DataNumStr(VarValue, sgl.BlinkTextItems[BlinkFieldNo].VarType, 0);

#ifdef GuiConst_CHARMODE_ANSI
          CharPtr = (GuiConst_TEXT PrefixGeneric *) sgl.VarNumTextStr;
#else // GuiConst_CHARMODE_ANSI
          for (P1=0; P1<=CharCnt; P1++)
            sgl.VarNumUnicodeTextStr[P1] = sgl.VarNumTextStr[P1];
          CharPtr = (GuiConst_TEXT *) sgl.VarNumUnicodeTextStr;
#endif // GuiConst_CHARMODE_ANSI
        }
#ifdef GuiConst_CHARMODE_ANSI
         strcpy(sgl.AnsiTextBuf, CharPtr);
#else // GuiConst_CHARMODE_ANSI
         GuiLib_UnicodeStrCpy(sgl.UnicodeTextBuf, CharPtr);
#endif // GuiConst_CHARMODE_ANSI
#ifdef   GuiConst_ARAB_CHARS_INUSE
         if (sgl.BlinkTextItems[BlinkFieldNo].TextPar.BitFlags &
             GuiLib_BITFLAG_REVERSEWRITING)
         {
           CharCnt = ArabicCorrection(
              sgl.UnicodeTextBuf, CharCnt,
             (sgl.BlinkTextItems[BlinkFieldNo].TextPar.BitFlags &
              GuiLib_BITFLAG_REVERSEWRITING) > 0);
         }
#endif // GuiConst_ARAB_CHARS_INUSE
#ifdef GuiConst_CHARMODE_ANSI
         CharPtr = sgl.AnsiTextBuf;
#else // GuiConst_CHARMODE_ANSI
         CharPtr = sgl.UnicodeTextBuf;
#endif // GuiConst_CHARMODE_ANSI
         PrepareText(CharPtr, CharCnt,0);

#ifdef GuiConst_DISP_VAR_NOW
         displayVarNow = 0;
#endif
      }

      if (CharNo > CharCnt)
      {
        SetCurFont(sgl.CurItem.TextPar[0].FontIndex);
        sgl.CurItem.TextPar[0] = TempTextPar;
        sgl.CurItem.TextLength[0] = TempTextLength;
        sgl.CurItem.FormatFieldWidth = TempFormatFieldWidth;
        sgl.CurItem.FormatDecimals = TempFormatDecimals;
        sgl.CurItem.FormatAlignment = TempFormatAlignment;
        sgl.CurItem.FormatFormat = TempFormatFormat;
        return;
      }

      if(CharNo > 0)
      {
#ifdef GuiConst_BLINK_LF_COUNTS
        if (*(CharPtr + (CharNo - 1)) != GuiLib_LINEFEED)
#endif
        {
          sgl.BlinkTextItems[BlinkFieldNo].Active = 0;
          sgl.BlinkTextItems[BlinkFieldNo].CharNo = CharNo;
        }
      }

#ifdef GuiConst_ITEM_TEXTBLOCK_INUSE
      if ((sgl.BlinkTextItems[BlinkFieldNo].ItemType == GuiLib_ITEM_TEXTBLOCK)||
          (sgl.BlinkTextItems[BlinkFieldNo].ItemType == GuiLib_ITEM_VARBLOCK))
      {
        if(CharNo > 0)
        {
          TextPixelLength(sgl.BlinkTextItems[BlinkFieldNo].TextPar.Ps,
                          CharCnt, TextXOfs);

          TextCharLineStart[0] = 0;
          TextCharLineEnd[0] = -1;

          LineCnt = 1 - sgl.BlinkTextItems[BlinkFieldNo].BlindLinesAtTop;
          if (LineCnt >= 1)
            LineCnt = 1;
          LineCnt2 = 1;
          P2 = 0;


#ifdef GuiConst_REMOTE_FONT_DATA
          GuiLib_RemoteDataReadBlock(
             (GuiConst_INT32U PrefixRom)GuiFont_ChPtrList[
              sgl.TextCharNdx[TextCharLineStart[LineCnt2 - 1]]],
              GuiLib_CHR_LINECTRL_OFS,
              CharHeader2);
#endif // GuiConst_REMOTE_FONT_DATA

          while (P2 < CharCnt)
          {
            while ((P2 < CharCnt - 1) &&
                !((ReadBytePtr(CharPtr + P2) == GuiLib_LINEFEED) ||
                ((ReadBytePtr(CharPtr + P2) != ' ') && (ReadBytePtr(CharPtr + P2 + 1) == ' ')) ||
                ((ReadBytePtr(CharPtr + P2) == '-') && (ReadBytePtr(CharPtr + P2 + 1) != ' '))))
              P2++;

            if (CalcCharsWidth(TextCharLineStart[LineCnt2 - 1], P2,
                               TextXOfs, &XStart, &XEnd) >
               (sgl.BlinkTextItems[BlinkFieldNo].X2 -
                sgl.BlinkTextItems[BlinkFieldNo].X1 + 1))
            {
              if (TextCharLineEnd[LineCnt2 - 1] == -1)
              {
                TextCharLineEnd[LineCnt2 - 1] = P2;
                TextCharLineStart[LineCnt2] = P2 + 1;
                TextCharLineEnd[LineCnt2] = -1;
              }
              else
              {
                TextCharLineStart[LineCnt2] = TextCharLineEnd[LineCnt2 - 1] + 1;
                while ((TextCharLineStart[LineCnt2] < P2) &&
                       (ReadBytePtr(CharPtr + TextCharLineStart[LineCnt2]) ==
                        ' '))
                  TextCharLineStart[LineCnt2]++;
                TextCharLineEnd[LineCnt2] = P2;
              }
              if (LineCnt >= GuiConst_MAX_PARAGRAPH_LINE_CNT)
              {
                P2 = CharCnt;
                break;
              }
              LineCnt++;
              if (LineCnt > 1)
                LineCnt2 = LineCnt;
              else
                TextCharLineStart[LineCnt2 - 1] = TextCharLineStart[LineCnt2];
            }
            else
              TextCharLineEnd[LineCnt2 - 1] = P2;
            if (ReadBytePtr(CharPtr + P2) == GuiLib_LINEFEED)
            {
              TextCharLineEnd[LineCnt2 - 1] = P2 - 1;
              TextCharLineStart[LineCnt2] = P2 + 1;
              TextCharLineEnd[LineCnt2] = -1;
              if (LineCnt >= GuiConst_MAX_PARAGRAPH_LINE_CNT)
              {
                P2 = CharCnt;
                break;
              }
              LineCnt++;
              if (LineCnt > 1)
                LineCnt2 = LineCnt;
              else
                TextCharLineStart[LineCnt2 - 1] = TextCharLineStart[LineCnt2];
            }
            P2++;
          }

            if (sgl.BlinkTextItems[BlinkFieldNo].TextPar.BitFlags &
                GuiLib_BITFLAG_REVERSEWRITING)
            {
              for (M = 0; M < LineCnt2 ; M++)
              {
                for (P2 = TextCharLineStart[M]; P2 <= (TextCharLineStart[M] +
                   ((TextCharLineEnd[M] - TextCharLineStart[M] + 1) / 2) - 1);
                     P2++)
                {
#ifdef GuiConst_REMOTE_FONT_DATA
                  TempOfs = sgl.TextCharNdx[P2];
                  sgl.TextCharNdx[P2] =
                     sgl.TextCharNdx[TextCharLineEnd[M] - (P2 - TextCharLineStart[M])];
                  sgl.TextCharNdx[TextCharLineEnd[M] - (P2 - TextCharLineStart[M])] =
                     TempOfs;
#else // GuiConst_REMOTE_FONT_DATA
                  TempPtr = sgl.TextCharPtrAry[P2];
                  sgl.TextCharPtrAry[P2] =
                     (GuiConst_INT8U PrefixRom *)sgl.TextCharPtrAry[
                     TextCharLineEnd[M] - (P2 - TextCharLineStart[M])];
                  sgl.TextCharPtrAry[TextCharLineEnd[M] - (P2 - TextCharLineStart[M])] =
                     (GuiConst_INT8U PrefixRom *)TempPtr;
#endif // GuiConst_REMOTE_FONT_DATA
                }
              }
              TextPixelLength(sgl.BlinkTextItems[BlinkFieldNo].TextPar.Ps,
                              CharCnt, TextXOfs);
            }

#ifdef GuiConst_TEXTBOX_FIELDS_ON
            if (sgl.BlinkTextItems[BlinkFieldNo].BlindLinesAtTop < 0)
              sgl.BlinkTextItems[BlinkFieldNo].BlindLinesAtTop = 0;
            sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1 -=
               sgl.BlinkTextItems[BlinkFieldNo].TextBoxScrollPos -
              (sgl.BlinkTextItems[BlinkFieldNo].TextBoxLineDist *
               sgl.BlinkTextItems[BlinkFieldNo].BlindLinesAtTop);
#endif // GuiConst_TEXTBOX_FIELDS_ON

            switch (sgl.BlinkTextItems[BlinkFieldNo].TextBoxVertAlignment)
            {
             case GuiLib_ALIGN_CENTER:
               sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1 +=
                  (sgl.BlinkTextItems[BlinkFieldNo].Y2 -
                   sgl.BlinkTextItems[BlinkFieldNo].Y1 + 1 -
                  (sgl.BlinkTextItems[BlinkFieldNo].YSize +
                  (LineCnt2 - 1) *
                   sgl.BlinkTextItems[BlinkFieldNo].TextBoxLineDist)) / 2;
               break;

             case GuiLib_ALIGN_RIGHT:
               sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1 +=
                  sgl.BlinkTextItems[BlinkFieldNo].Y2 -
                  sgl.BlinkTextItems[BlinkFieldNo].Y1 + 1 -
                 (sgl.BlinkTextItems[BlinkFieldNo].YSize +
                 (LineCnt2 - 1) *
                  sgl.BlinkTextItems[BlinkFieldNo].TextBoxLineDist);
               break;
            }

            for (N = 0; N < LineCnt2; N++)
            {
              if (((CharNo - 1) <= TextCharLineEnd[N])
               && ((CharNo - 1) >= TextCharLineStart[N]))
              {
                if (sgl.BlinkTextItems[BlinkFieldNo].TextPar.BitFlags &
                    GuiLib_BITFLAG_REVERSEWRITING)
                  CharNo = TextCharLineStart[N] + TextCharLineEnd[N] + 2 - CharNo;

                sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 =
                   sgl.BlinkTextItems[BlinkFieldNo].X1;

                LineLen = CalcCharsWidth(TextCharLineStart[N],
                                         TextCharLineEnd[N],
                                         TextXOfs,
                                         &XStart,
                                         &XEnd);
                switch (sgl.BlinkTextItems[BlinkFieldNo].TextBoxHorzAlignment)
                {
                  case GuiLib_ALIGN_CENTER:
                   sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 +=
                      (sgl.BlinkTextItems[BlinkFieldNo].X2 -
                       sgl.BlinkTextItems[BlinkFieldNo].X1 + LineLen - 1) / 2;
                   break;

                  case GuiLib_ALIGN_RIGHT:
                   sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 +=
                      sgl.BlinkTextItems[BlinkFieldNo].X2 -
                      sgl.BlinkTextItems[BlinkFieldNo].X1 + LineLen - 1;
                   break;
                }

                sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 -= XStart;
                LineLen = CalcCharsWidth(CharNo - 1,
                                         CharNo - 1,
                                         TextXOfs,
                                         &XStart,
                                         &XEnd);
                sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2 =
                   sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 + XEnd;
                sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 += XStart;
                sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY2 =
                   sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1 +
                   sgl.BlinkTextItems[BlinkFieldNo].YSize - 1;

                sgl.BlinkTextItems[BlinkFieldNo].Active = 1;
                break;
              }

#ifndef GuiConst_BLINK_LF_COUNTS
              if ((N+1) < LineCnt2)
                if ((TextCharLineEnd[N]+1) != TextCharLineStart[N+1])
                  CharNo++;
#endif

              sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1 +=
                 sgl.BlinkTextItems[BlinkFieldNo].TextBoxLineDist;
            }
        }
        else
        {
          sgl.BlinkTextItems[BlinkFieldNo].Active = 1;
          sgl.BlinkTextItems[BlinkFieldNo].CharNo = CharNo;
        }
      }
      else
#endif // GuiConst_ITEM_TEXTBLOCK_INUSE
      {
        if (sgl.BlinkTextItems[BlinkFieldNo].TextPar.BitFlags &
            GuiLib_BITFLAG_REVERSEWRITING)
        {
          for (N = 0; N < CharCnt / 2; N++)
          {
#ifdef GuiConst_REMOTE_FONT_DATA
            TempOfs = sgl.TextCharNdx[N];
            sgl.TextCharNdx[N] =
               sgl.TextCharNdx[CharCnt - 1 - N];
            sgl.TextCharNdx[CharCnt - 1 - N] =
               TempOfs;
#else
            TempPtr = sgl.TextCharPtrAry[N];
            sgl.TextCharPtrAry[N] = (GuiConst_INT8U PrefixRom *)
               sgl.TextCharPtrAry[CharCnt - 1 - N];
            sgl.TextCharPtrAry[CharCnt - 1 - N] =
              (GuiConst_INT8U PrefixRom *)TempPtr;
#endif
          }
          CharNo =  CharCnt + 1 - CharNo;
        }

        TextPixelLen = TextPixelLength(sgl.BlinkTextItems[BlinkFieldNo].TextPar.Ps,
                          CharCnt, TextXOfs);

        switch (sgl.BlinkTextItems[BlinkFieldNo].TextPar.Alignment)
        {
          case GuiLib_ALIGN_CENTER:
            if (CharCnt > 0)
                sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 -= TextPixelLen / 2;
              break;
          case GuiLib_ALIGN_RIGHT:
            sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 -= TextPixelLen - 1;
              break;
        }

        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2 = sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 +
           TextPixelLen - 1;

        if (CharNo)
        {
          if (sgl.BlinkTextItems[BlinkFieldNo].TextPar.Ps == GuiLib_PS_OFF)
          {
            sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 =
               sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 + TextXOfs[CharNo-1] - 1;
            sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2 =
               sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 +
               sgl.BlinkTextItems[BlinkFieldNo].XSize;
          }
          else if ((sgl.BlinkTextItems[BlinkFieldNo].TextPar.Ps == GuiLib_PS_NUM) &&
                   (sgl.TextPsMode[CharNo - 1] == 0))
          {
               sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 =
                  sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 + TextXOfs[CharNo - 1] - 1;
               sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2 =
                  sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 +
                  sgl.BlinkTextItems[BlinkFieldNo].PsNumWidth +
                  sgl.BlinkTextItems[BlinkFieldNo].PsSpace;
          }
          else
          {
#ifdef GuiConst_REMOTE_FONT_DATA
            GuiLib_RemoteDataReadBlock((GuiConst_INT32U PrefixRom)
               GuiFont_ChPtrList[sgl.TextCharNdx[CharNo - 1]],
               GuiLib_CHR_LINECTRL_OFS, CharHeader);
            sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 =
               sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 +
               TextXOfs[CharNo-1] + CharHeader[GuiLib_CHR_XLEFT_OFS] - 1;
#else
            sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 =
               sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 + TextXOfs[CharNo - 1] +
               ReadBytePtr(sgl.TextCharPtrAry[CharNo - 1] +
               GuiLib_CHR_XLEFT_OFS) - 1;
#endif
#ifdef GuiConst_REMOTE_FONT_DATA
          sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2 =
             sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 +
             CharHeader[GuiLib_CHR_XWIDTH_OFS] + 1;
#else
          sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2 =
             sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1 +
             ReadBytePtr(sgl.TextCharPtrAry[CharNo - 1] +
             GuiLib_CHR_XWIDTH_OFS) + 1;
#endif
          }
          sgl.BlinkTextItems[BlinkFieldNo].Active = 1;
        }
        else
        {
          sgl.BlinkTextItems[BlinkFieldNo].Active = 1;
          sgl.BlinkTextItems[BlinkFieldNo].CharNo = CharNo;
        }
      }
      SetCurFont(sgl.CurItem.TextPar[0].FontIndex);
      sgl.CurItem.TextPar[0] = TempTextPar;
      sgl.CurItem.TextLength[0] = TempTextLength;
      sgl.CurItem.FormatFieldWidth = TempFormatFieldWidth;
      sgl.CurItem.FormatDecimals = TempFormatDecimals;
      sgl.CurItem.FormatAlignment = TempFormatAlignment;
      sgl.CurItem.FormatFormat = TempFormatFormat;

    }

    if (sgl.BlinkTextItems[BlinkFieldNo].Active)
    {
      if (Rate < 1)
        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate = 1;
      else
        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate = Rate;
      if (sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate < 255)
      {
        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxState =
           sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate -
          (sgl.RefreshClock % sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate);
        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted =
           ((sgl.RefreshClock / sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate) % 2) ==
             0;
        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxLast =
           sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted;
        if (sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted && sgl.DisplayWriting)
          GuiLib_InvertBox(sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1,
                           sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1,
                           sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2,
                           sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY2);
      }
      else
      {
        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxState =
             sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate;
        if (sgl.DisplayWriting)
          GuiLib_InvertBox(sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1,
                           sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1,
                           sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2,
                           sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY2);

        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted =
                        !sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted;
        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxLast =
                        sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted;
      }
    }
  }
#else // GuiConst_BLINK_FIELDS_OFF
  gl.Dummy1_16U = BlinkFieldNo;   // To avoid compiler warning
  gl.Dummy2_16U = CharNo;   // To avoid compiler warning
  gl.Dummy1_16S = Rate;   // To avoid compiler warning
#endif // GuiConst_BLINK_FIELDS_OFF
}

//------------------------------------------------------------------------------
void GuiLib_BlinkBoxMarkedItemStop(
   GuiConst_INT16U BlinkFieldNo)
{
#ifndef GuiConst_BLINK_FIELDS_OFF
  if ((BlinkFieldNo >= GuiConst_BLINK_FIELDS_MAX) ||
      !sgl.BlinkTextItems[BlinkFieldNo].InUse)
    return;

  if (sgl.BlinkTextItems[BlinkFieldNo].Active &&
      sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate &&
      sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted)
  {
    if (sgl.DisplayWriting)
    {
      GuiLib_InvertBox(sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX1,
                       sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY1,
                       sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxX2,
                       sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxY2);
      sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted =
         !sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted;
      sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxLast =
         sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxInverted;
    }
  }
  sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate = 0;
  sgl.BlinkTextItems[BlinkFieldNo].Active = 0;
#else // GuiConst_BLINK_FIELDS_OFF
  gl.Dummy1_16U = BlinkFieldNo;   // To avoid compiler warning
#endif // GuiConst_BLINK_FIELDS_OFF
}

//------------------------------------------------------------------------------
void GuiLib_BlinkBoxMarkedItemUpdate(
   GuiConst_INT16U BlinkFieldNo)
{
#ifndef GuiConst_BLINK_FIELDS_OFF
  if ((BlinkFieldNo >= GuiConst_BLINK_FIELDS_MAX) ||
      !sgl.BlinkTextItems[BlinkFieldNo].InUse)
    return;

  if (sgl.BlinkTextItems[BlinkFieldNo].Active &&
     ((sgl.BlinkTextItems[BlinkFieldNo].ItemType == GuiLib_ITEM_VAR) ||
      (sgl.BlinkTextItems[BlinkFieldNo].ItemType == GuiLib_ITEM_VARBLOCK)))
    GuiLib_BlinkBoxMarkedItem(
       BlinkFieldNo,
       sgl.BlinkTextItems[BlinkFieldNo].CharNo,
       sgl.BlinkTextItems[BlinkFieldNo].BlinkBoxRate);
#else // GuiConst_BLINK_FIELDS_OFF
  gl.Dummy1_16U = BlinkFieldNo;   // To avoid compiler warning
#endif // GuiConst_BLINK_FIELDS_OFF
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#endif // GuiConst_BLINK_SUPPORT_ON

#ifdef GuiConst_ITEM_TOUCHAREA_INUSE
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GuiConst_INT32S GuiLib_TouchCheck(
   GuiConst_INT16S X,
   GuiConst_INT16S Y)
{
  GuiConst_INT32S TouchSearch;
  GuiConst_INT32S XX, YY;
  GuiConst_INT32S XL, XR, YT, YB;
  GuiConst_INT32S TouchArea;

  if (sgl.TouchAdjustActive)
  {
    XX = 10 * (GuiConst_INT32S)X;
    YY = 10 * (GuiConst_INT32S)Y;
    XL = sgl.TouchAdjustXTL +
       (YY - sgl.TouchAdjustYTL) * (sgl.TouchAdjustXBL - sgl.TouchAdjustXTL) /
       (sgl.TouchAdjustYBL - sgl.TouchAdjustYTL);
    XR = sgl.TouchAdjustXTR +
       (YY - sgl.TouchAdjustYTR) * (sgl.TouchAdjustXBR - sgl.TouchAdjustXTR) /
       (sgl.TouchAdjustYBR - sgl.TouchAdjustYTR);
    YT = sgl.TouchAdjustYTL +
       (XX - sgl.TouchAdjustXTL) * (sgl.TouchAdjustYTR - sgl.TouchAdjustYTL) /
       (sgl.TouchAdjustXTR - sgl.TouchAdjustXTL);
    YB = sgl.TouchAdjustYBL +
       (XX - sgl.TouchAdjustXBL) * (sgl.TouchAdjustYBR - sgl.TouchAdjustYBL) /
       (sgl.TouchAdjustXBR - sgl.TouchAdjustXBL);
    sgl.TouchConvertX = GuiConst_DISPLAY_WIDTH * (XX - XL) / (XR - XL);
    sgl.TouchConvertY = GuiConst_DISPLAY_HEIGHT * (YY - YT) / (YB - YT);
  }
  else
  {
    sgl.TouchConvertX = X;
    sgl.TouchConvertY = Y;
  }

  TouchArea = -1;
  if ((sgl.TouchConvertX >= 0) && (sgl.TouchConvertX < GuiConst_DISPLAY_WIDTH) &&
      (sgl.TouchConvertY >= 0) && (sgl.TouchConvertY < GuiConst_DISPLAY_HEIGHT))
    for (TouchSearch = 0; TouchSearch < sgl.TouchAreaCnt; TouchSearch++)
      if ((sgl.TouchConvertX >= sgl.TouchAreas[TouchSearch].X1) &&
          (sgl.TouchConvertX <= sgl.TouchAreas[TouchSearch].X2) &&
          (sgl.TouchConvertY >= sgl.TouchAreas[TouchSearch].Y1) &&
          (sgl.TouchConvertY <= sgl.TouchAreas[TouchSearch].Y2))
      {
        if (TouchArea == -1)
          TouchArea = sgl.TouchAreas[TouchSearch].IndexNo;
        else if (sgl.TouchAreas[TouchSearch].IndexNo < TouchArea)
          TouchArea = sgl.TouchAreas[TouchSearch].IndexNo;
      }
  return TouchArea;
}

//------------------------------------------------------------------------------
GuiConst_INT32S GuiLib_TouchGet(
   GuiConst_INT16S X,
   GuiConst_INT16S Y,
   GuiConst_INT16S* TouchX,
   GuiConst_INT16S* TouchY)
{
  GuiConst_INT32S Result;

  Result = GuiLib_TouchCheck(X, Y);

  *TouchX = sgl.TouchConvertX;
  *TouchY = sgl.TouchConvertY;

  return (Result);
}

//------------------------------------------------------------------------------
void GuiLib_TouchAdjustReset(void)
{
  sgl.TouchAdjustActive = 0;
  sgl.TouchAdjustInUse[0] = 0;
  sgl.TouchAdjustInUse[1] = 0;
  sgl.TouchAdjustInUse[2] = 0;
  sgl.TouchAdjustInUse[3] = 0;
}

//------------------------------------------------------------------------------
void GuiLib_TouchAdjustSet(
   GuiConst_INT16S XTrue,
   GuiConst_INT16S YTrue,
   GuiConst_INT16S XMeasured,
   GuiConst_INT16S YMeasured)
{
  GuiConst_INT8U I;
  GuiConst_INT32S XTL, YTL, XTR, YTR, XBL, YBL, XBR, YBR, XL, XR, YT, YB;

  if (YTrue < GuiConst_DISPLAY_HEIGHT / 2)
  {
    if (XTrue < GuiConst_DISPLAY_WIDTH / 2)
      I = 0;
    else
      I = 1;
  }
  else
  {
    if (XTrue < GuiConst_DISPLAY_WIDTH / 2)
      I = 2;
    else
      I = 3;
  }

  sgl.TouchAdjustInUse[I] = 1;

  sgl.TouchAdjustXTrue[I] = XTrue;
  sgl.TouchAdjustYTrue[I] = YTrue;
  sgl.TouchAdjustXMeasured[I] = XMeasured;
  sgl.TouchAdjustYMeasured[I] = YMeasured;

  if (sgl.TouchAdjustInUse[0] && sgl.TouchAdjustInUse[3])
  {
    sgl.TouchAdjustActive = 1;
    if (!sgl.TouchAdjustInUse[1])
    {
      sgl.TouchAdjustInUse[1] = 1;
      sgl.TouchAdjustXTrue[1] = sgl.TouchAdjustXTrue[3];
      sgl.TouchAdjustYTrue[1] = sgl.TouchAdjustYTrue[0];
      sgl.TouchAdjustXMeasured[1] = sgl.TouchAdjustXMeasured[3];
      sgl.TouchAdjustYMeasured[1] = sgl.TouchAdjustYMeasured[0];
    }
    if (!sgl.TouchAdjustInUse[2])
    {
      sgl.TouchAdjustInUse[2] = 1;
      sgl.TouchAdjustXTrue[2] = sgl.TouchAdjustXTrue[0];
      sgl.TouchAdjustYTrue[2] = sgl.TouchAdjustYTrue[3];
      sgl.TouchAdjustXMeasured[2] = sgl.TouchAdjustXMeasured[0];
      sgl.TouchAdjustYMeasured[2] = sgl.TouchAdjustYMeasured[3];
    }
  }
  else if (sgl.TouchAdjustInUse[1] && sgl.TouchAdjustInUse[2])
  {
    sgl.TouchAdjustActive = 1;
    if (!sgl.TouchAdjustInUse[0])
    {
      sgl.TouchAdjustInUse[0] = 1;
      sgl.TouchAdjustXTrue[0] = sgl.TouchAdjustXTrue[2];
      sgl.TouchAdjustYTrue[0] = sgl.TouchAdjustYTrue[1];
      sgl.TouchAdjustXMeasured[0] = sgl.TouchAdjustXMeasured[2];
      sgl.TouchAdjustYMeasured[0] = sgl.TouchAdjustYMeasured[1];
    }
    if (!sgl.TouchAdjustInUse[3])
    {
      sgl.TouchAdjustInUse[3] = 1;
      sgl.TouchAdjustXTrue[3] = sgl.TouchAdjustXTrue[1];
      sgl.TouchAdjustYTrue[3] = sgl.TouchAdjustYTrue[2];
      sgl.TouchAdjustXMeasured[3] = sgl.TouchAdjustXMeasured[1];
      sgl.TouchAdjustYMeasured[3] = sgl.TouchAdjustYMeasured[2];
    }
  }

  if (sgl.TouchAdjustActive)
  {
    XTL = (10 * sgl.TouchAdjustXMeasured[1]) - ((10 * sgl.TouchAdjustXTrue[1] *
       (sgl.TouchAdjustXMeasured[1] - sgl.TouchAdjustXMeasured[0])) /
       (sgl.TouchAdjustXTrue[1] - sgl.TouchAdjustXTrue[0]));
    XTR = (10 * sgl.TouchAdjustXMeasured[0]) +
       ((10 * (GuiConst_DISPLAY_WIDTH - sgl.TouchAdjustXTrue[0]) *
       (sgl.TouchAdjustXMeasured[1] - sgl.TouchAdjustXMeasured[0])) /
       (sgl.TouchAdjustXTrue[1] - sgl.TouchAdjustXTrue[0]));
    XBL = (10 * sgl.TouchAdjustXMeasured[3]) - ((10 * sgl.TouchAdjustXTrue[3] *
       (sgl.TouchAdjustXMeasured[3] - sgl.TouchAdjustXMeasured[2])) /
       (sgl.TouchAdjustXTrue[3] - sgl.TouchAdjustXTrue[2]));
    XBR = (10 * sgl.TouchAdjustXMeasured[2]) +
       ((10 * (GuiConst_DISPLAY_WIDTH - sgl.TouchAdjustXTrue[2]) *
       (sgl.TouchAdjustXMeasured[3] - sgl.TouchAdjustXMeasured[2])) /
       (sgl.TouchAdjustXTrue[3] - sgl.TouchAdjustXTrue[2]));

    YT = 5 * (sgl.TouchAdjustYTrue[0] + sgl.TouchAdjustYTrue[1]);
    YB = 5 * (sgl.TouchAdjustYTrue[2] + sgl.TouchAdjustYTrue[3]);

    sgl.TouchAdjustXTL = XBL - (YB * (XBL - XTL) / (YB - YT));
    sgl.TouchAdjustXBL =
       XTL + (((10 * GuiConst_DISPLAY_HEIGHT) - YT) * (XBL - XTL) / (YB - YT));
    sgl.TouchAdjustXTR = XBR - (YB * (XBR - XTR) / (YB - YT));
    sgl.TouchAdjustXBR =
       XTR + (((10 * GuiConst_DISPLAY_HEIGHT) - YT) * (XBR - XTR) / (YB - YT));

    YTL = (10 * sgl.TouchAdjustYMeasured[2]) - ((10 * sgl.TouchAdjustYTrue[2] *
       (sgl.TouchAdjustYMeasured[2] - sgl.TouchAdjustYMeasured[0])) /
       (sgl.TouchAdjustYTrue[2] - sgl.TouchAdjustYTrue[0]));
    YBL = (10 * sgl.TouchAdjustYMeasured[0]) +
       ((10 * (GuiConst_DISPLAY_HEIGHT - sgl.TouchAdjustYTrue[0]) *
       (sgl.TouchAdjustYMeasured[2] - sgl.TouchAdjustYMeasured[0])) /
       (sgl.TouchAdjustYTrue[2] - sgl.TouchAdjustYTrue[0]));
    YTR = (10 * sgl.TouchAdjustYMeasured[3]) - ((10 * sgl.TouchAdjustYTrue[3] *
       (sgl.TouchAdjustYMeasured[3] - sgl.TouchAdjustYMeasured[1])) /
       (sgl.TouchAdjustYTrue[3] - sgl.TouchAdjustYTrue[1]));
    YBR = (10 * sgl.TouchAdjustYMeasured[1]) +
       ((10 * (GuiConst_DISPLAY_HEIGHT - sgl.TouchAdjustYTrue[1]) *
       (sgl.TouchAdjustYMeasured[3] - sgl.TouchAdjustYMeasured[1])) /
       (sgl.TouchAdjustYTrue[3] - sgl.TouchAdjustYTrue[1]));

    XL = 5 * (sgl.TouchAdjustXTrue[0] + sgl.TouchAdjustXTrue[2]);
    XR = 5 * (sgl.TouchAdjustXTrue[1] + sgl.TouchAdjustXTrue[3]);

    sgl.TouchAdjustYTL = YTR - (XR * (YTR - YTL) / (XR - XL));
    sgl.TouchAdjustYTR =
       YTL + (((10 * GuiConst_DISPLAY_WIDTH) - XL) * (YTR - YTL) / (XR - XL));
    sgl.TouchAdjustYBL = YBR - (XR * (YBR - YBL) / (XR - XL));
    sgl.TouchAdjustYBR =
       YBL + (((10 * GuiConst_DISPLAY_WIDTH) - XL) * (YBR - YBL) / (XR - XL));
  }
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#endif // GuiConst_ITEM_TOUCHAREA_INUSE

#ifdef GuiConst_ITEM_SCROLLBOX_INUSE
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static void ScrollBox_ShowLineStruct(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16U StructToCallIndex,
   GuiConst_INT16S X,
   GuiConst_INT16S Y,
   GuiConst_INT8U ColorInvert)
{
  GuiLib_StructPtr StructToCall;
#ifdef GuiConst_CLIPPING_SUPPORT_ON
  GuiConst_INT16S RemClippingX1, RemClippingY1, RemClippingX2, RemClippingY2;
#endif //GuiConst_CLIPPING_SUPPORT_ON

  if (StructToCallIndex != 0xFFFF)
  {
    sgl.DisplayLevel++;
#ifdef GuiConst_CLIPPING_SUPPORT_ON
    RemClippingX1 = sgl.CurItem.ClipRectX1;
    RemClippingY1 = sgl.CurItem.ClipRectY1;
    RemClippingX2 = sgl.CurItem.ClipRectX2;
    RemClippingY2 = sgl.CurItem.ClipRectY2;
#endif // GuiConst_CLIPPING_SUPPORT_ON
    memcpy(&sgl.CurItem, &sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxItem,
       sizeof(GuiLib_ItemRec));
    sgl.CurItem.RX = X;
    sgl.CurItem.RY = Y;
#ifdef GuiConst_CLIPPING_SUPPORT_ON
    sgl.CurItem.ClipRectX1 = RemClippingX1;
    sgl.CurItem.ClipRectY1 = RemClippingY1;
    sgl.CurItem.ClipRectX2 = RemClippingX2;
    sgl.CurItem.ClipRectY2 = RemClippingY2;
#endif // GuiConst_CLIPPING_SUPPORT_ON
    StructToCall = (GuiLib_StructPtr)
#ifdef GuiConst_REMOTE_STRUCT_DATA
       GetRemoteStructData(StructToCallIndex);
#else // GuiConst_REMOTE_STRUCT_DATA
       (GuiLib_StructPtr)ReadWord(GuiStruct_StructPtrList[StructToCallIndex]);
#endif // GuiConst_REMOTE_STRUCT_DATA

    if (ColorInvert == GuiLib_COL_INVERT_ON)
    {
#ifdef GuiConst_CURSOR_SUPPORT_ON
      if (sgl.ScrollBoxesAry[ScrollBoxIndex].ContainsCursorFields)
        ColorInvert = GuiLib_COL_INVERT_IF_CURSOR;
#endif // GuiConst_CURSOR_SUPPORT_ON
    }
    else
    {
#ifdef GuiConst_BITMAP_SUPPORT_ON
      UpdateBackgroundBitmap();
#endif
    }

    DrawStructure(StructToCall, ColorInvert);
    ResetLayerBufPtr();
    sgl.DisplayLevel--;
  }
}

//------------------------------------------------------------------------------
static void ScrollBox_ShowLineBlock(
   GuiConst_INTCOLOR Color,
   GuiConst_INT8U Transparent,
   GuiConst_INT16S X1,
   GuiConst_INT16S Y1,
   GuiConst_INT16S X2,
   GuiConst_INT16S Y2)
{
  if (!Transparent)
    GuiLib_FillBox(X1, Y1, X2, Y2, Color);
}

//------------------------------------------------------------------------------
static void ScrollBox_ShowBarBlock(
   GuiConst_INTCOLOR ForeColor,
   GuiConst_INTCOLOR BackColor,
   GuiConst_INT8U Thickness,
   GuiConst_INT16S X,
   GuiConst_INT16S Y,
   GuiConst_INT16S SizeX,
   GuiConst_INT16S SizeY)
{
  GuiConst_INT8U T;
  GuiConst_INT16S BX1, BY1, BX2, BY2;

  if (Thickness > 0)
    for (T = 0; T < Thickness; T++)
    {
      BX1 = X + T;
      BY1 = Y + T;
      BX2 = X + SizeX - 1 - T;
      BY2 = Y + SizeY - 1 - T;
      GuiLib_Box(BX1, BY1, BX2, BY2, ForeColor);
    }
  BX1 = X + Thickness;
  BY1 = Y + Thickness;
  BX2 = X + SizeX - 1 - Thickness;
  BY2 = Y + SizeY - 1 - Thickness;
  GuiLib_FillBox(BX1, BY1, BX2, BY2, BackColor);
}

//------------------------------------------------------------------------------
static void ScrollBox_SetTopLine(
   GuiConst_INT8U ScrollBoxIndex)
{
    GuiConst_INT16U LowerLimtA=0;
  if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollMode == 0)
  {
    sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
       sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] -
       sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs;
    GuiLib_LIMIT_MINMAX(sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine,
       LowerLimtA, sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
       sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines);
  }
  else
    sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
       sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] -
       sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs;
}

//------------------------------------------------------------------------------
static void ScrollBox_DrawScrollLine(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16S LineNdx)
{
  GuiConst_INT16U N;
  GuiConst_INT16S SX1, SY1;
  GuiConst_INT16S X1, Y1, X2, Y2;
#ifdef GuiConst_CLIPPING_SUPPORT_ON
  GuiConst_INT16S RemClippingX1, RemClippingY1, RemClippingX2, RemClippingY2;
#endif // GuiConst_CLIPPING_SUPPORT_ON

  if ((LineNdx < sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine) ||
      (LineNdx >= sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine +
                  sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines))
    return;

  X1 = sgl.ScrollBoxesAry[ScrollBoxIndex].X1 +
       sgl.ScrollBoxesAry[ScrollBoxIndex].LineOffsetX;
  Y1 = sgl.ScrollBoxesAry[ScrollBoxIndex].Y1 +
       sgl.ScrollBoxesAry[ScrollBoxIndex].LineOffsetY +
       (LineNdx - sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine) *
       sgl.ScrollBoxesAry[ScrollBoxIndex].LineVerticalOffset;
  X2 = X1 + sgl.ScrollBoxesAry[ScrollBoxIndex].LineSizeX - 1;
  Y2 = Y1 + sgl.ScrollBoxesAry[ScrollBoxIndex].LineSizeY - 1;

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  RemClippingX1 = sgl.CurItem.ClipRectX1;
  RemClippingY1 = sgl.CurItem.ClipRectY1;
  RemClippingX2 = sgl.CurItem.ClipRectX2;
  RemClippingY2 = sgl.CurItem.ClipRectY2;
  GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX1, X1, X2);
  GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY1, Y1, Y2);
  GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX2, X1, X2);
  GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY2, Y1, Y2);
  GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                     sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON

  if ((LineNdx >= 0) &&
      (LineNdx < sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines))
  {
    sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollLineDataFunc(LineNdx);

    SX1 = X1 + sgl.ScrollBoxesAry[ScrollBoxIndex].LineStructOffsetX;
    SY1 = Y1 + sgl.ScrollBoxesAry[ScrollBoxIndex].LineStructOffsetY;
    for (N = 0; N <= GuiConst_SCROLLITEM_MARKERS_MAX; N++)
    {
      if (N < GuiConst_SCROLLITEM_MARKERS_MAX)
      {
        if ((sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[N] >= 0) &&
            (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerSize[N] >= 1))
        {
          if ((LineNdx >= sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[N]) &&
              (LineNdx <= (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[N] +
               sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerSize[N] - 1)))
          {
            ScrollBox_ShowLineBlock(
               sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerColor[N],
               sgl.ScrollBoxesAry[ScrollBoxIndex].
               MarkerColorTransparent[N], X1, Y1, X2, Y2);
            switch (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerDrawingOrder[N])
            {
              case 0:
                ScrollBox_ShowLineStruct(ScrollBoxIndex,
                   sgl.ScrollBoxesAry[ScrollBoxIndex].LineStructIndex, SX1, SY1,
                   GuiLib_COL_INVERT_ON);
                if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStructIndex[N] !=
                    0xFFFF)
                  ScrollBox_ShowLineStruct(ScrollBoxIndex,
                     sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStructIndex[N],
                     SX1, SY1, GuiLib_COL_INVERT_ON);
                break;

              case 1:
                if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStructIndex[N] !=
                    0xFFFF)
                  ScrollBox_ShowLineStruct(ScrollBoxIndex,
                     sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStructIndex[N],
                     SX1, SY1, GuiLib_COL_INVERT_ON);
                ScrollBox_ShowLineStruct(ScrollBoxIndex,
                   sgl.ScrollBoxesAry[ScrollBoxIndex].LineStructIndex, SX1, SY1,
                   GuiLib_COL_INVERT_ON);
                break;

              case 2:
                ScrollBox_ShowLineStruct(ScrollBoxIndex,
                   sgl.ScrollBoxesAry[ScrollBoxIndex].LineStructIndex, SX1, SY1,
                   GuiLib_COL_INVERT_ON);
                break;

              case 3:
                if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStructIndex[N] !=
                    0xFFFF)
                  ScrollBox_ShowLineStruct(ScrollBoxIndex,
                     sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStructIndex[N],
                     SX1, SY1, GuiLib_COL_INVERT_ON);
                break;
            }

            break;
          }
        }
      }
      else
      {
        ScrollBox_ShowLineBlock(
           sgl.ScrollBoxesAry[ScrollBoxIndex].LineColor,
           sgl.ScrollBoxesAry[ScrollBoxIndex].LineColorTransparent,
           X1, Y1, X2, Y2);
        ScrollBox_ShowLineStruct(ScrollBoxIndex,
           sgl.ScrollBoxesAry[ScrollBoxIndex].LineStructIndex, SX1, SY1,
           GuiLib_COL_INVERT_OFF);
      }
    }
  }
  else
    ScrollBox_ShowLineBlock(sgl.ScrollBoxesAry[ScrollBoxIndex].LineColor,
       sgl.ScrollBoxesAry[ScrollBoxIndex].LineColorTransparent,
       X1, Y1, X2, Y2);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  sgl.CurItem.ClipRectX1 = RemClippingX1;
  sgl.CurItem.ClipRectY1 = RemClippingY1;
  sgl.CurItem.ClipRectX2 = RemClippingX2;
  sgl.CurItem.ClipRectY2 = RemClippingY2;
  GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                     sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_Init(
   GuiConst_INT8U ScrollBoxIndex,
   void (*DataFuncPtr) (GuiConst_INT16S LineIndex),
   GuiConst_INT16S NoOfLines,
   GuiConst_INT16S ActiveLine)
{
  GuiConst_INT16U StructToCallIndex;
  GuiLib_StructPtr StructToCall;
  GuiLib_ItemRec RemCurItem;
#ifdef GuiConst_CURSOR_SUPPORT_ON
  GuiConst_INT8U RemCursorInUse;
#endif // GuiConst_CURSOR_SUPPORT_ON

  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_READ) ||
      (ActiveLine >= NoOfLines))
    return (0);

  memcpy(&RemCurItem, &sgl.CurItem, sizeof(GuiLib_ItemRec));

  sgl.GlobalScrollBoxIndex = ScrollBoxIndex;

  memcpy(&sgl.CurItem, &sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxItem,
     sizeof(GuiLib_ItemRec));
  StructToCallIndex = sgl.ScrollBoxesAry[ScrollBoxIndex].LineStructIndex;
  if (StructToCallIndex != 0xFFFF)
  {
    sgl.DisplayLevel++;
    StructToCall = (GuiLib_StructPtr)
#ifdef GuiConst_REMOTE_STRUCT_DATA
       GetRemoteStructData(StructToCallIndex);
#else
       (GuiLib_StructPtr)ReadWord(GuiStruct_StructPtrList[StructToCallIndex]);
#endif
    sgl.NextScrollLineReading = 1;
    sgl.InitialDrawing = 1;
#ifdef GuiConst_CURSOR_SUPPORT_ON
    RemCursorInUse = sgl.CursorInUse;
    sgl.ScrollBoxesAry[ScrollBoxIndex].ContainsCursorFields = 0;
    sgl.CursorInUse = (GuiLib_ActiveCursorFieldNo >= 0);
    sgl.CursorFieldFound = -1;
    sgl.CursorActiveFieldFound = 0;
#endif // GuiConst_CURSOR_SUPPORT_ON
    DrawStructure(StructToCall, GuiLib_COL_INVERT_OFF);
    ResetLayerBufPtr();
#ifdef GuiConst_CURSOR_SUPPORT_ON
    sgl.InitialDrawing = 0;
    if (sgl.CursorFieldFound == -1)
    {
      sgl.CursorInUse = 0;
      GuiLib_ActiveCursorFieldNo = -1;
    }
    else
    {
      sgl.ScrollBoxesAry[ScrollBoxIndex].ContainsCursorFields = 1;
      if (sgl.CursorActiveFieldFound == 0)
      {
        GuiLib_ActiveCursorFieldNo = sgl.CursorFieldFound;

        DrawCursorItem(1);
      }
    }
    sgl.CursorInUse = sgl.CursorInUse | RemCursorInUse;
#endif // GuiConst_CURSOR_SUPPORT_ON
    sgl.NextScrollLineReading = 0;
    sgl.DisplayLevel--;
  }

  SetCurFont(sgl.CurItem.TextPar[0].FontIndex);
  if ((sgl.ScrollBoxesAry[ScrollBoxIndex].LineSizeY == 0) &&
      (sgl.ScrollBoxesAry[ScrollBoxIndex].LineSizeY2 == 0))
  {
    sgl.ScrollBoxesAry[ScrollBoxIndex].LineSizeY = sgl.CurFont->BaseLine;
    sgl.ScrollBoxesAry[ScrollBoxIndex].LineSizeY2 =
       sgl.CurFont->YSize - sgl.CurFont->BaseLine - 1;
  }

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  GuiLib_SetClipping(sgl.CurItem.ClipRectX1,sgl.CurItem.ClipRectY1,
                     sgl.CurItem.ClipRectX2,sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON

  StructToCallIndex = sgl.ScrollBoxesAry[ScrollBoxIndex].MakeUpStructIndex;
  if (StructToCallIndex != 0xFFFF)
  {
    sgl.DisplayLevel++;
    memcpy(&sgl.CurItem, &sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxItem,
       sizeof(GuiLib_ItemRec));
    sgl.CurItem.RX = sgl.ScrollBoxesAry[sgl.GlobalScrollBoxIndex].X1;
    sgl.CurItem.RY = sgl.ScrollBoxesAry[sgl.GlobalScrollBoxIndex].Y1;
    StructToCall = (GuiLib_StructPtr)
#ifdef GuiConst_REMOTE_STRUCT_DATA
       GetRemoteStructData(StructToCallIndex);
#else
       (GuiLib_StructPtr)ReadWord(GuiStruct_StructPtrList[StructToCallIndex]);
#endif
    DrawStructure(StructToCall,GuiLib_COL_INVERT_OFF);
    ResetLayerBufPtr();
    sgl.DisplayLevel--;
  }

  sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollLineDataFunc = DataFuncPtr;
  sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] = ActiveLine;
  sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine = ActiveLine;
  sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines = NoOfLines;
  if ((sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollMode == 0) &&
      (NoOfLines < sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines))
    sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines = NoOfLines;
  sgl.ScrollBoxesAry[ScrollBoxIndex].InUse = GuiLib_SCROLL_STRUCTURE_USED;
  ScrollBox_SetTopLine(ScrollBoxIndex);
  GuiLib_ScrollBox_Redraw(ScrollBoxIndex);
  sgl.ScrollBoxesAry[ScrollBoxIndex].LastScrollTopLine = 0xFFFF;

  memcpy(&sgl.CurItem, &RemCurItem, sizeof(GuiLib_ItemRec));

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_Redraw(
   GuiConst_INT8U ScrollBoxIndex)
{
  GuiConst_INT16S N, ScrollStartLine, ScrollStopLine;
  GuiLib_ItemRec RemCurItem;
#ifndef GuiConst_SCROLLITEM_BAR_NONE
#define GuiLib_SCROLL_REDRAW_VAR
#else
#ifndef GuiConst_SCROLLITEM_INDICATOR_NONE
#define GuiLib_SCROLL_REDRAW_VAR
#endif
#endif
#ifdef GuiLib_SCROLL_REDRAW_VAR
  GuiLib_StructPtr StructToCall;
  GuiConst_INT16U StructToCallIndex;
  GuiConst_INT16S SX1, SY1;
  GuiConst_INT16S X1, Y1;
#ifdef GuiConst_CLIPPING_SUPPORT_ON
  GuiConst_INT16S SX2, SY2;
  GuiConst_INT16S X2, Y2;
  GuiConst_INT16S RemClippingX1, RemClippingY1, RemClippingX2, RemClippingY2;
#endif // GuiConst_CLIPPING_SUPPORT_ON
#endif // GuiLib_SCROLL_REDRAW_VAR
#ifndef GuiConst_SCROLLITEM_BAR_NONE
  GuiConst_INT16S BarMarkerY;
  GuiConst_INT16S BarMarkerHeight;
  GuiConst_INT16S BarMarkerMovementDY;
  GuiConst_INT32S N1, N2;
#endif // GuiConst_SCROLLITEM_BAR_NONE
  GuiConst_INT32S BackColor;

  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED))
    return (0);

  memcpy(&RemCurItem, &sgl.CurItem, sizeof(GuiLib_ItemRec));

  sgl.GlobalScrollBoxIndex = ScrollBoxIndex;

  ScrollStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
  ScrollStopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine +
     sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines - 1;
  if (sgl.ScrollBoxesAry[ScrollBoxIndex].LastScrollTopLine ==
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine)
  {
    if ((sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine == -1) ||
        (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] == -1))
    {
      if (sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine !=
          sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0])
      {
        if (sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine == -1)
        {
          ScrollStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];
          ScrollStopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];
        }
        else
        {
          ScrollStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine;
          ScrollStopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine;
        }
      }
    }
    else if (sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine <
             sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0])
    {
      ScrollStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine;
      if (ScrollStartLine < sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine)
        ScrollStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
      ScrollStopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];
    }
    else if (sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine >
             sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0])
    {
      ScrollStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];
      ScrollStopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine;
      GuiLib_LIMIT_MAX(ScrollStartLine,
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine +
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines - 1);
    }
  }

  if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollLineDataFunc != 0)
    for (N = ScrollStartLine; N <= ScrollStopLine; N++)
      ScrollBox_DrawScrollLine(ScrollBoxIndex, N);

  sgl.ScrollBoxesAry[ScrollBoxIndex].LastScrollTopLine =
     sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
  sgl.ScrollBoxesAry[ScrollBoxIndex].LastMarkerLine =
     sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];

#ifndef GuiConst_SCROLLITEM_BAR_NONE
  if (sgl.ScrollBoxesAry[ScrollBoxIndex].BarType != GuiLib_MARKER_NONE)
  {
    SX1 = sgl.ScrollBoxesAry[ScrollBoxIndex].BarPositionX;
    SY1 = sgl.ScrollBoxesAry[ScrollBoxIndex].BarPositionY;
    X1 = SX1 + sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerLeftOffset;
    Y1 = SY1 + sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerTopOffset;
#ifdef GuiConst_CLIPPING_SUPPORT_ON
    SX2 = SX1 + sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeX - 1;
    SY2 = SY1 + sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeY - 1;
    X2 = SX2 - sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerRightOffset;
    Y2 = SY2 - sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerBottomOffset;
    RemClippingX1 = sgl.CurItem.ClipRectX1;
    RemClippingY1 = sgl.CurItem.ClipRectY1;
    RemClippingX2 = sgl.CurItem.ClipRectX2;
    RemClippingY2 = sgl.CurItem.ClipRectY2;
    GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX1, SX1, SX2);
    GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY1, SY1, SY2);
    GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX2, SX1, SX2);
    GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY2, SY1, SY2);
    GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                       sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON

    StructToCallIndex = sgl.ScrollBoxesAry[ScrollBoxIndex].BarStructIndex;
    if (StructToCallIndex != 0xFFFF)
    {
      ScrollBox_ShowBarBlock(
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarForeColor,
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarBackColor,
         0,
         SX1,
         SY1,
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeX,
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeY);

      sgl.DisplayLevel++;
      memcpy(&sgl.CurItem,
             &sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxItem,
             sizeof(GuiLib_ItemRec));
      sgl.CurItem.RX = SX1;
      sgl.CurItem.RY = SY1;
      StructToCall = (GuiLib_StructPtr)
#ifdef GuiConst_REMOTE_STRUCT_DATA
         GetRemoteStructData(StructToCallIndex);
#else
         (GuiLib_StructPtr)ReadWord(GuiStruct_StructPtrList[StructToCallIndex]);
#endif
      DrawStructure(StructToCall, GuiLib_COL_INVERT_OFF);
      ResetLayerBufPtr();
      sgl.DisplayLevel--;
    }
    else
      ScrollBox_ShowBarBlock(
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarForeColor,
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarBackColor,
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarThickness,
         SX1,
         SY1,
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeX,
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeY);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
    sgl.CurItem.ClipRectX1 = RemClippingX1;
    sgl.CurItem.ClipRectY1 = RemClippingY1;
    sgl.CurItem.ClipRectX2 = RemClippingX2;
    sgl.CurItem.ClipRectY2 = RemClippingY2;
    GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                       sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON

    if (sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines >
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines)
    {
#ifdef GuiConst_CLIPPING_SUPPORT_ON
      RemClippingX1 = sgl.CurItem.ClipRectX1;
      RemClippingY1 = sgl.CurItem.ClipRectY1;
      RemClippingX2 = sgl.CurItem.ClipRectX2;
      RemClippingY2 = sgl.CurItem.ClipRectY2;
      GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX1, X1, X2);
      GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY1, Y1, Y2);
      GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX2, X1, X2);
      GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY2, Y1, Y2);
      GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                         sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON

      BarMarkerHeight = 0;
      BarMarkerMovementDY = sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeY -
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerBottomOffset -
         sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerTopOffset;

      switch (sgl.ScrollBoxesAry[ScrollBoxIndex].BarType)
      {
        case GuiLib_MARKER_ICON:
          sgl.CurFont = (GuiLib_FontRecPtr)ReadWord(GuiFont_FontList[
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerIconFont]);
          BarMarkerHeight = sgl.CurFont->YSize;
          break;

        case GuiLib_MARKER_BITMAP:
          BarMarkerHeight =
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerBitmapHeight;
          break;

        case GuiLib_MARKER_FIXED_BLOCK:
          BarMarkerHeight =
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeX -
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerLeftOffset -
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerRightOffset;
          break;

        case GuiLib_MARKER_VARIABLE_BLOCK:
          BarMarkerHeight =
             (((10 * BarMarkerMovementDY *
             sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines) + 5) /
             sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines) / 10;
          GuiLib_LIMIT_MIN(BarMarkerHeight, 4);
          break;
      }

      N1 = sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines;
      N2 = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
      GuiLib_LIMIT_MINMAX(N2, 0, N1);
      BarMarkerY = (((10 * (BarMarkerMovementDY - BarMarkerHeight) *
         N2) + 5) / N1) / 10;

      switch (sgl.ScrollBoxesAry[ScrollBoxIndex].BarType)
      {
        case GuiLib_MARKER_ICON:
          sgl.CurItem.X1 = X1 + sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerIconOffsetX;
          sgl.CurItem.Y1 = Y1 + BarMarkerY +
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerIconOffsetY +
             sgl.CurFont->BaseLine;
          sgl.CurItem.TextPar[0].FontIndex =
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerIconFont;
          sgl.CurItem.TextPar[0].Alignment = GuiLib_ALIGN_LEFT;
          sgl.CurItem.TextPar[0].Ps = GuiLib_PS_OFF;
          sgl.CurItem.TextPar[0].BitFlags = 0;
          sgl.CurItem.TextPar[0].BackBoxSizeX = 0;
          sgl.CurItem.TextPar[0].BackBorderPixels = 0;
          DrawText(sgl.ScrollBoxesAry[ScrollBoxIndex].BarIconPtr, 1, 0,
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerForeColor,
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerBackColor,
             sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerTransparent);
          break;

        case GuiLib_MARKER_BITMAP:
          if (sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerBitmapIsTransparent)
            BackColor =
               sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerBitmapTranspColor;
          else
            BackColor = -1;
          GuiLib_ShowBitmap(sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerBitmapIndex,
             X1, Y1 + BarMarkerY, BackColor);
          break;

        case GuiLib_MARKER_FIXED_BLOCK:
        case GuiLib_MARKER_VARIABLE_BLOCK:
          if (sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerTransparent)
            GuiLib_Box(X1, Y1 + BarMarkerY,
               X1 + sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeX -
               sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerLeftOffset -
               sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerRightOffset - 1,
               Y1 + BarMarkerY + BarMarkerHeight - 1,
               sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerForeColor);
          else
            GuiLib_BorderBox(X1, Y1 + BarMarkerY,
               X1 + sgl.ScrollBoxesAry[ScrollBoxIndex].BarSizeX -
               sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerLeftOffset -
               sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerRightOffset - 1,
               Y1 + BarMarkerY + BarMarkerHeight - 1,
               sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerForeColor,
               sgl.ScrollBoxesAry[ScrollBoxIndex].BarMarkerBackColor);
          break;
      }

#ifdef GuiConst_CLIPPING_SUPPORT_ON
      sgl.CurItem.ClipRectX1 = RemClippingX1;
      sgl.CurItem.ClipRectY1 = RemClippingY1;
      sgl.CurItem.ClipRectX2 = RemClippingX2;
      sgl.CurItem.ClipRectY2 = RemClippingY2;
      GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                         sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON
    }
  }
#endif

#ifndef GuiConst_SCROLLITEM_INDICATOR_NONE
  if (sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorType != GuiLib_INDICATOR_NONE)
  {
    SX1 = sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorPositionX;
    SY1 = sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorPositionY;
    X1 = SX1 + sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerLeftOffset;
    Y1 = SY1 + sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerTopOffset;
#ifdef GuiConst_CLIPPING_SUPPORT_ON
    SX2 = SX1 + sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorSizeX - 1;
    SY2 = SY1 + sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorSizeY - 1;
    X2 = SX2 - sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerRightOffset;
    Y2 = SY2 - sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerBottomOffset;
    RemClippingX1 = sgl.CurItem.ClipRectX1;
    RemClippingY1 = sgl.CurItem.ClipRectY1;
    RemClippingX2 = sgl.CurItem.ClipRectX2;
    RemClippingY2 = sgl.CurItem.ClipRectY2;
    GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX1, SX1, SX2);
    GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY1, SY1, SY2);
    GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX2, SX1, SX2);
    GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY2, SY1, SY2);
    GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                       sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON

    StructToCallIndex = sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorStructIndex;
    if (StructToCallIndex != 0xFFFF)
    {
      ScrollBox_ShowBarBlock(
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorForeColor,
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorBackColor,
         0,
         SX1,
         SY1,
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorSizeX,
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorSizeY);

      sgl.DisplayLevel++;
      memcpy(&sgl.CurItem,
             &sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxItem,
             sizeof(GuiLib_ItemRec));
      sgl.CurItem.RX = SX1;
      sgl.CurItem.RY = SY1;
      StructToCall = (GuiLib_StructPtr)
#ifdef GuiConst_REMOTE_STRUCT_DATA
         GetRemoteStructData(StructToCallIndex);
#else
         (GuiLib_StructPtr)ReadWord(GuiStruct_StructPtrList[StructToCallIndex]);
#endif
      DrawStructure(StructToCall, GuiLib_COL_INVERT_OFF);
      ResetLayerBufPtr();
      sgl.DisplayLevel--;
    }
    else
      ScrollBox_ShowBarBlock(
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorForeColor,
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorBackColor,
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorThickness,
         SX1,
         SY1,
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorSizeX,
         sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorSizeY);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
    sgl.CurItem.ClipRectX1 = RemClippingX1;
    sgl.CurItem.ClipRectY1 = RemClippingY1;
    sgl.CurItem.ClipRectX2 = RemClippingX2;
    sgl.CurItem.ClipRectY2 = RemClippingY2;
    GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                       sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON

    if ((sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorLine >= 0) &&
        (sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorLine >=
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine) &&
        (sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorLine <
        (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine +
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines)))
    {
#ifdef GuiConst_CLIPPING_SUPPORT_ON
      GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX1, X1, X2);
      GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY1, Y1, Y2);
      GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectX2, X1, X2);
      GuiLib_LIMIT_MINMAX(sgl.CurItem.ClipRectY2, Y1, Y2);
      GuiLib_SetClipping(sgl.CurItem.ClipRectX1, sgl.CurItem.ClipRectY1,
                         sgl.CurItem.ClipRectX2, sgl.CurItem.ClipRectY2);
#endif // GuiConst_CLIPPING_SUPPORT_ON

      switch (sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorType)
      {
        case GuiLib_MARKER_ICON:
          sgl.CurFont = (GuiLib_FontRecPtr)ReadWord(GuiFont_FontList[
             sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerIconFont]);
          sgl.CurItem.X1 =
             X1 + sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerIconOffsetX;
          sgl.CurItem.Y1 =
             Y1 + sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerIconOffsetY +
             sgl.CurFont->BaseLine +
             sgl.ScrollBoxesAry[ScrollBoxIndex].LineVerticalOffset *
             (sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorLine -
             sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine);
          sgl.CurItem.TextPar[0].FontIndex =
             sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerIconFont;
          sgl.CurItem.TextPar[0].Alignment = GuiLib_ALIGN_LEFT;
          sgl.CurItem.TextPar[0].Ps = GuiLib_PS_OFF;
          sgl.CurItem.TextPar[0].BitFlags = 0;
          sgl.CurItem.TextPar[0].BackBoxSizeX = 0;
          sgl.CurItem.TextPar[0].BackBorderPixels = 0;
          DrawText(sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorIconPtr, 1, 0,
                   sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerForeColor,
                   sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerBackColor,
                   sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerTransparent);
          break;

        case GuiLib_MARKER_BITMAP:
          if (sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerBitmapIsTransparent)
            BackColor =
               sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerBitmapTranspColor;
          else
            BackColor = -1;
          GuiLib_ShowBitmap(
             sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorMarkerBitmapIndex,
             X1, Y1 + sgl.ScrollBoxesAry[ScrollBoxIndex].LineVerticalOffset *
             (sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorLine -
             sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine), BackColor);
          break;
      }
    }
  }
#endif // GuiConst_SCROLLITEM_INDICATOR_NONE

  memcpy(&sgl.CurItem, &RemCurItem, sizeof(GuiLib_ItemRec));

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_RedrawLine(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16U ScrollLine)
{
  GuiLib_ItemRec RemCurItem;

  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED) ||
      (ScrollLine > (sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1)) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollLineDataFunc == 0))
    return (0);

  memcpy(&RemCurItem, &sgl.CurItem, sizeof(GuiLib_ItemRec));
  sgl.GlobalScrollBoxIndex = ScrollBoxIndex;

  ScrollBox_DrawScrollLine(ScrollBoxIndex, ScrollLine);

  memcpy(&sgl.CurItem, &RemCurItem, sizeof(GuiLib_ItemRec));

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_Close(
   GuiConst_INT8U ScrollBoxIndex)
{
  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED))
    return (0);

  sgl.ScrollBoxesAry[ScrollBoxIndex].InUse = GuiLib_SCROLL_STRUCTURE_READ;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_Down(
   GuiConst_INT8U ScrollBoxIndex)
{
  GuiConst_INT16U ScrollBottomLine;
  GuiConst_INT16S RemScrollTopLine;
  GuiConst_INT16S RemMarkerStartLine;

  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED))
    return (0);

  RemScrollTopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
  RemMarkerStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];

  ScrollBottomLine = (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine +
     sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines - 1);

  if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxType)
  {
    if (ScrollBottomLine >= (sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1))
    {
      if ((sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 1)
#ifdef GuiConst_SCROLL_MODE_WRAP_AROUND
         || (sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 2)
#endif
                                                        )
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine = 0;
    }
    else
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine++;
  }
  else if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] >= 0)
  {
    if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollMode == 0)
    {
      if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] ==
         (sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1))
      {
        if ((sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 1)
#ifdef GuiConst_SCROLL_MODE_WRAP_AROUND
           || (sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 2)
#endif
                                                          )
        {
          sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine = 0;
          sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] = 0;
        }
      }
      else if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] <
         ScrollBottomLine - sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs)
        sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0]++;
      else
      {
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine++;
        GuiLib_LIMIT_MAX(sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine,
           sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
           sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines);
        sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0]++;
      }
    }
    else
    {
      if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] ==
         (sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1))
      {
        if ((sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 1)
#ifdef GuiConst_SCROLL_MODE_WRAP_AROUND
           || (sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 2)
#endif
                                                          )
        {
          sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
             -sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs;
          sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] = 0;
        }
      }
      else
      {
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine++;
        sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0]++;
      }
    }
  }

  if ((sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine != RemScrollTopLine) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] != RemMarkerStartLine))
  {
    GuiLib_ScrollBox_Redraw(ScrollBoxIndex);
    return (1);
  }
  else
    return (0);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_Up(
   GuiConst_INT8U ScrollBoxIndex)
{
  GuiConst_INT16S RemScrollTopLine;
  GuiConst_INT16S RemMarkerStartLine;

  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED))
    return (0);

  RemScrollTopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
  RemMarkerStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];

  if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxType)
  {
    if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine == 0)
    {
      if ((sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 1)
#ifdef GuiConst_SCROLL_MODE_WRAP_AROUND
         || (sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 2)
#endif
                                                        )
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
           sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
           sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines;
        GuiLib_LIMIT_MIN(sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine, 0);
    }
    else
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine--;
  }
  else if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] >= 0)
  {
    if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollMode == 0)
    {
      if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] == 0)
      {
        if ((sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 1)
#ifdef GuiConst_SCROLL_MODE_WRAP_AROUND
           || (sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 2)
#endif
                                                          )
        {
          sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
             sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
             sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines;
          GuiLib_LIMIT_MIN(sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine, 0);
          sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] =
             sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1;
        }
      }
      else if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] >
               sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine +
               sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs)
        sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0]--;
      else
      {
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine--;
        GuiLib_LIMIT_MIN(sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine, 0);
        sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0]--;
      }
    }
    else
    {
      if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] == 0)
      {
        if ((sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 1)
#ifdef GuiConst_SCROLL_MODE_WRAP_AROUND
           || (sgl.ScrollBoxesAry[ScrollBoxIndex].WrapMode == 2)
#endif
                                                          )
        {
          sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
             sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1 -
             sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs;
          sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] =
             sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1;
        }
      }
      else
      {
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine--;
        sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0]--;
      }
    }
  }

  if ((sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine != RemScrollTopLine) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] != RemMarkerStartLine))
  {
    GuiLib_ScrollBox_Redraw(ScrollBoxIndex);
    return (1);
  }
  else
    return (0);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_Home(
   GuiConst_INT8U ScrollBoxIndex)
{
  GuiConst_INT16S RemScrollTopLine;
  GuiConst_INT16S RemMarkerStartLine;

  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED))
    return (0);

  RemScrollTopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
  RemMarkerStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];

  if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxType)
    sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine = 0;
  else
  {
    if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollMode == 0)
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine = 0;
    else
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
         -sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs;
    if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] >= 0)
      sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] = 0;
  }

  if ((sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine != RemScrollTopLine) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] != RemMarkerStartLine))
  {
    GuiLib_ScrollBox_Redraw(ScrollBoxIndex);
    return (1);
  }
  else
    return (0);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_End(
   GuiConst_INT8U ScrollBoxIndex)
{
  GuiConst_INT16S RemScrollTopLine;
  GuiConst_INT16S RemMarkerStartLine;

  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED))
    return (0);

  RemScrollTopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
  RemMarkerStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];

  if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxType)
    sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine = GuiLib_GET_MAX(
       sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
       sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines, 0);
  else
  {
    if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollMode == 0)
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine = GuiLib_GET_MAX(
         sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines, 0);
    else
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
         sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1 -
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs;
    if (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] >= 0)
      sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] =
         sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1;
  }

  if ((sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine != RemScrollTopLine) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] != RemMarkerStartLine))
  {
    GuiLib_ScrollBox_Redraw(ScrollBoxIndex);
    return (1);
  }
  else
    return (0);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_To_Line(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16S NewLine)
{
  GuiConst_INT16S RemScrollTopLine;
  GuiConst_INT16S RemMarkerStartLine;
  GuiConst_INT16S TopLine;
  GuiConst_INT16S LowerLimtA = 0;

  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED) ||
      (NewLine >= sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines))
    return(0);

  RemScrollTopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine;
  RemMarkerStartLine = sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0];

  if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollBoxType)
  {
    TopLine = sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
              sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines;
    GuiLib_LIMIT_MIN(TopLine, 0);
    if (NewLine > TopLine)
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine = TopLine;
    else
      sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine = NewLine;
  }
  else if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollMode == 0)
  {
    if ((NewLine != -1) &&
        ((NewLine < sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine) ||
        (NewLine >= (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine +
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines))))
    {
      if (NewLine > (sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
          sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines +
          sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs))
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
           sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
           sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines;
      else
        sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
           NewLine - sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs;

      GuiLib_LIMIT_MINMAX(sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine,
         NewLine - sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines + 1,
         NewLine + sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines - 1);
      GuiLib_LIMIT_MINMAX(sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine, LowerLimtA,
         sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
         sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines);
    }
  }
  else
    sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
       NewLine - sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollStartOfs;
  sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] = NewLine;

  if ((sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine != RemScrollTopLine) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[0] != RemMarkerStartLine))
  {
    GuiLib_ScrollBox_Redraw(ScrollBoxIndex);
    return (1);
  }
  else
    return (0);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_SetLineMarker(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16U ScrollLineMarkerIndex,
   GuiConst_INT16S StartLine,
   GuiConst_INT16U Size)
{
  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED) ||
      (ScrollLineMarkerIndex >= GuiConst_SCROLLITEM_MARKERS_MAX) ||
      (StartLine >= sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines))
    return (0);

  sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[ScrollLineMarkerIndex] =
     GuiLib_GET_MINMAX(StartLine, -1,
     (GuiConst_INT16S)sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1);
  if ((ScrollLineMarkerIndex == 0) && (Size > 1))
    Size = 1;
  sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerSize[ScrollLineMarkerIndex] = Size;
  if (ScrollLineMarkerIndex == 0)
    ScrollBox_SetTopLine(ScrollBoxIndex);

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT16S GuiLib_ScrollBox_GetActiveLine(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16U ScrollLineMarkerIndex)
{
  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED) ||
      (ScrollLineMarkerIndex >= GuiConst_SCROLLITEM_MARKERS_MAX))
    return (-1);

  return (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerStartLine[ScrollLineMarkerIndex]);
}

//------------------------------------------------------------------------------
GuiConst_INT16S GuiLib_ScrollBox_GetActiveLineCount(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16U ScrollLineMarkerIndex)
{
  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED) ||
      (ScrollLineMarkerIndex >= GuiConst_SCROLLITEM_MARKERS_MAX))
    return (-1);

  return (sgl.ScrollBoxesAry[ScrollBoxIndex].MarkerSize[ScrollLineMarkerIndex]);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_SetIndicator(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16S StartLine)
{
#ifdef GuiConst_SCROLLITEM_INDICATOR_NONE
  gl.Dummy1_8U = ScrollBoxIndex;   // To avoid compiler warning
  gl.Dummy1_16S = StartLine;   // To avoid compiler warning
  return (0);
#else
  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED) ||
      (StartLine >= sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines))
    return (0);

  sgl.ScrollBoxesAry[ScrollBoxIndex].IndicatorLine = GuiLib_GET_MINMAX(
     StartLine, -1,
     (GuiConst_INT16S)sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines - 1);

  return (1);
#endif
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_ScrollBox_SetTopLine(
   GuiConst_INT8U ScrollBoxIndex,
   GuiConst_INT16S TopLine)
{
  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED) ||
      (TopLine >= sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines))
    return (0);

  if (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollMode == 0)
    sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine =
       GuiLib_GET_MINMAX(TopLine, 0,
       sgl.ScrollBoxesAry[ScrollBoxIndex].NumberOfLines -
       sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollVisibleLines);

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT16S GuiLib_ScrollBox_GetTopLine(
   GuiConst_INT8U ScrollBoxIndex)
{
  if ((ScrollBoxIndex >= GuiConst_SCROLLITEM_BOXES_MAX) ||
      (sgl.ScrollBoxesAry[ScrollBoxIndex].InUse != GuiLib_SCROLL_STRUCTURE_USED))
    return (-1);

  return (sgl.ScrollBoxesAry[ScrollBoxIndex].ScrollTopLine);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#endif // GuiConst_ITEM_SCROLLBOX_INUSE

#ifdef GuiConst_ITEM_GRAPH_INUSE
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#ifdef GuiConst_CLIPPING_SUPPORT_ON
//------------------------------------------------------------------------------
static void Graph_SetClipping(
   GuiConst_INT8U GraphIndex)
{
  GuiLib_SetClipping(sgl.GraphAry[GraphIndex].GraphItem.ClipRectX1,
                     sgl.GraphAry[GraphIndex].GraphItem.ClipRectY1,
                     sgl.GraphAry[GraphIndex].GraphItem.ClipRectX2,
                     sgl.GraphAry[GraphIndex].GraphItem.ClipRectY2);
}

//------------------------------------------------------------------------------
static void Graph_ResetClipping(void)
{
  GuiLib_ResetClipping();
}
#endif // GuiConst_CLIPPING_SUPPORT_ON

//------------------------------------------------------------------------------
static void Graph_CalcScaleX(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex)
{
  GuiConst_INT32S D1,D2;

  D1 = (sgl.GraphAry[GraphIndex].GraphItem.X2 -
       sgl.GraphAry[GraphIndex].GraphItem.X1 -
       sgl.GraphAry[GraphIndex].OriginOffsetX);
  D1 = D1 * 10000;
  D2 = (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].NumbersMaxValue -
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].NumbersMinValue);
  D1 = D1/D2;
  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Scale = D1;
}

//------------------------------------------------------------------------------
static void Graph_CalcScaleY(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex)
{
  GuiConst_INT32S D1,D2;

  D1 = (sgl.GraphAry[GraphIndex].GraphItem.Y2 -
       sgl.GraphAry[GraphIndex].GraphItem.Y1-
       sgl.GraphAry[GraphIndex].OriginOffsetY);
  D1 = D1 * 10000;
  D2 = (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].NumbersMaxValue -
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].NumbersMinValue);
  D1 = D1/D2;
  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Scale= D1;
}

//------------------------------------------------------------------------------
static GuiConst_INT32S Graph_CalcNumbersMaxValue(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex,
   GuiConst_INT8U AxisType)
{
  GuiConst_INT32S MV;

  MV = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][AxisType].NumbersMaxValue;
  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][AxisType].TicksMinor)
    MV -= sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][AxisType].NumbersAtEnd *
          sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][AxisType].NumbersStepMinor;
  else if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][AxisType].TicksMajor)
    MV -= sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][AxisType].NumbersAtEnd *
          sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][AxisType].NumbersStepMajor;
  return(MV);
}

//------------------------------------------------------------------------------
static void Graph_DrawXAxis(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex)
{
  GuiConst_INT16S X, Y;
  GuiConst_INT16S DX, DY;
  GuiConst_INT32S TX, TY;
  #ifdef GuiConst_FLOAT_SUPPORT_ON
  double TDX;
  #endif
  GuiConst_INT32S F;
  GuiConst_INT16S HW;
  GuiConst_INT32S MV;
  GuiConst_INT16U StrLen;
  GuiConst_INT16U I;
  GuiConst_INT8U Align;

  Y = sgl.GraphAry[GraphIndex].OrigoY +
      sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Offset;

  MV = Graph_CalcNumbersMaxValue(GraphIndex, AxisIndex, GuiLib_GRAPHAXIS_X);

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Line)
  {
    X = sgl.GraphAry[GraphIndex].GraphItem.X2 -
        sgl.GraphAry[GraphIndex].GraphItem.X1 + 1;
    for (I = 0; I < sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y]; I++)
      if (sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].Offset < X)
        X = sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].Offset;
    X += sgl.GraphAry[GraphIndex].OriginOffsetX;
    if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
        LineNegative)
      GuiLib_FillBox(sgl.GraphAry[GraphIndex].GraphItem.X1,
                     Y,
                     sgl.GraphAry[GraphIndex].GraphItem.X1 + X - 1,
                     Y,
                     sgl.GraphAry[GraphIndex].ForeColor);
    if ((sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y] > 1) &&
         sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         LineBetweenAxes)
      GuiLib_FillBox(sgl.GraphAry[GraphIndex].GraphItem.X1 + X - 1,
                     Y,
                     sgl.GraphAry[GraphIndex].GraphItem.X1 +
                     sgl.GraphAry[GraphIndex].OriginOffsetX,
                     Y,
                     sgl.GraphAry[GraphIndex].ForeColor);
    GuiLib_FillBox(sgl.GraphAry[GraphIndex].GraphItem.X1 +
                   sgl.GraphAry[GraphIndex].OriginOffsetX,
                   Y,
                   sgl.GraphAry[GraphIndex].GraphItem.X2,
                   Y,
                   sgl.GraphAry[GraphIndex].ForeColor);
  }

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Arrow)
  {
    DX = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         ArrowLength;
    HW = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         ArrowWidth / 2;
    for (DY = -HW; DY <= HW; DY++)
      GuiLib_Line(sgl.GraphAry[GraphIndex].GraphItem.X2 - DX,
                  Y + DY,
                  sgl.GraphAry[GraphIndex].GraphItem.X2,
                  Y,
                  sgl.GraphAry[GraphIndex].ForeColor);
  }

  Graph_CalcScaleX(GraphIndex, AxisIndex);

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].TicksMajor)
  {
    HW = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         TicksMajorWidth / 2;
    TX = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         NumbersMinValue;
    F = TX % sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
             NumbersStepMajor;
    if (F != 0)
    {
      TX -= F;
      if (TX < sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
               NumbersMinValue)
        TX += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
              NumbersStepMajor;
    }
    while (TX <= MV)
    {
      DX = sgl.GraphAry[GraphIndex].OrigoX + ((TX -
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
           NumbersMinValue) *
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Scale) /
           10000;
      if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
          NumbersAtOrigo ||
         (TX != sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
                NumbersMinValue))
        GuiLib_FillBox(
           DX - HW,
           Y,
           DX - HW +
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
           TicksMajorWidth - 1,
           Y + sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
           TicksMajorLength - 1,
           sgl.GraphAry[GraphIndex].ForeColor);
      TX += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
            NumbersStepMajor;
    }
  }

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].TicksMinor)
  {
    HW = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         TicksMinorWidth / 2;
    TX = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         NumbersMinValue;
    F = TX % sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
             NumbersStepMinor;
    if (F != 0)
    {
      TX -= F;
      if (TX < sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
               NumbersMinValue)
        TX += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
              NumbersStepMinor;
    }
    while (TX <= MV)
    {
      DX = sgl.GraphAry[GraphIndex].OrigoX + ((TX -
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
           NumbersMinValue) *
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Scale) /
           10000;
      if ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
          NumbersAtOrigo ||
         (TX != sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
                NumbersMinValue)) &&
         ((!sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
            TicksMajor) ||
         (TX % sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
               NumbersStepMajor != 0)))
        GuiLib_FillBox(
           DX - HW,
           Y,
           DX - HW +
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
           TicksMinorWidth - 1,
           Y + sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
           TicksMinorLength - 1,
           sgl.GraphAry[GraphIndex].ForeColor);
      TX += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
            NumbersStepMinor;
    }
  }

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Numbers)
  {
    memcpy(&sgl.CurItem, &sgl.GraphAry[GraphIndex].GraphItem, sizeof(GuiLib_ItemRec));

    DY = Y;
    if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
       TicksMajor)
      DY += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         TicksMajorLength;
    SetCurFont(sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].FontIndex);
    DY += ReadByte(sgl.CurFont->BaseLine);
    DY += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
       NumbersOffset;

    TX = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
       NumbersMinValue;
    F = TX % sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
             NumbersStepMajor;
    if (F != 0)
    {
      TX -= F;
      if (TX < sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
               NumbersMinValue)
        TX += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
              NumbersStepMajor;
    }
    switch (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].FormatAlignment)
    {
      case GuiLib_FORMAT_ALIGNMENT_LEFT:
        Align = GuiLib_ALIGN_LEFT;
        break;
      case GuiLib_FORMAT_ALIGNMENT_CENTER:
        Align = GuiLib_ALIGN_CENTER;
        break;
      case GuiLib_FORMAT_ALIGNMENT_RIGHT:
        Align = GuiLib_ALIGN_RIGHT;
        break;
    }
    while (TX <= MV)
    {
      DX = sgl.GraphAry[GraphIndex].OrigoX + ((TX -
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
           NumbersMinValue) *
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Scale) /
           10000;
      if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
          NumbersAtOrigo ||
         (TX != sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
                NumbersMinValue))
      {
        #ifdef GuiConst_FLOAT_SUPPORT_ON
        TDX = TX;
        #endif
        GuiLib_DrawVar(
           DX,
           DY,
           sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].FontIndex,
           #ifdef GuiConst_FLOAT_SUPPORT_ON
           &TDX,
           GuiLib_VAR_DOUBLE,
           #else
           &TX,
           GuiLib_VAR_SIGNED_LONG,
           #endif
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].FormatFormat,
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].FormatFieldWidth,
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].FormatAlignment,
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].FormatDecimals,
           ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
              BitFlags & GuiLib_BITFLAG_FORMATSHOWSIGN) > 0),
           ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
              BitFlags & GuiLib_BITFLAG_FORMATZEROPADDING) > 0),
           ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
              BitFlags & GuiLib_BITFLAG_FORMATTRAILINGZEROS) > 0),
           ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
              BitFlags & GuiLib_BITFLAG_FORMATTHOUSANDSSEP) > 0),
           Align,
           sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].Ps,
           1,   // Transparent
           ((sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].BitFlags &
            GuiLib_BITFLAG_UNDERLINE) > 0),
           0,
           0,
           0,
           0,
           sgl.GraphAry[GraphIndex].GraphItem.ForeColor,
           sgl.GraphAry[GraphIndex].GraphItem.BackColor);
      }
      TX += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
         NumbersStepMajor;
    }
  }
}

//------------------------------------------------------------------------------
static void Graph_DrawYAxis(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex)
{
  GuiConst_INT16S X, Y;
  GuiConst_INT16S DX, DY;
  GuiConst_INT32S TX, TY;
  #ifdef GuiConst_FLOAT_SUPPORT_ON
  double TDY;
  #endif
  GuiConst_INT32S F;
  GuiConst_INT16S HW;
  GuiConst_INT32S MV;
  GuiConst_INT16U StrLen;
  GuiConst_INT16U I;
  GuiConst_INT8U Align;

  X = sgl.GraphAry[GraphIndex].OrigoX +
      sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Offset;

  MV = Graph_CalcNumbersMaxValue(GraphIndex, AxisIndex, GuiLib_GRAPHAXIS_Y);

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Line)
  {
    Y = 0;
    for (I = 0; I < sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X]; I++)
      if (sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].Offset > Y)
        Y = sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].Offset;
    Y = sgl.GraphAry[GraphIndex].OriginOffsetY - Y;
    if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
        LineNegative)
      GuiLib_FillBox(X,
                     sgl.GraphAry[GraphIndex].GraphItem.Y2 - Y,
                     X,
                     sgl.GraphAry[GraphIndex].GraphItem.Y2,
                     sgl.GraphAry[GraphIndex].ForeColor);
    if ((sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X] > 1) &&
         sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         LineBetweenAxes)
      GuiLib_FillBox(X,
                     sgl.GraphAry[GraphIndex].GraphItem.Y2 -
                     sgl.GraphAry[GraphIndex].OriginOffsetY,
                     X,
                     sgl.GraphAry[GraphIndex].GraphItem.Y2 - Y,
                     sgl.GraphAry[GraphIndex].ForeColor);
    GuiLib_FillBox(X,
                   sgl.GraphAry[GraphIndex].GraphItem.Y1,
                   X,
                   sgl.GraphAry[GraphIndex].GraphItem.Y2 -
                   sgl.GraphAry[GraphIndex].OriginOffsetY,
                   sgl.GraphAry[GraphIndex].ForeColor);
  }

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Arrow)
  {
    DY = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         ArrowLength;
    HW = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         ArrowWidth / 2;
    for (DX = -HW; DX <= HW; DX++)
      GuiLib_Line(X - DX,
                  sgl.GraphAry[GraphIndex].GraphItem.Y1 + DY,
                  X,
                  sgl.GraphAry[GraphIndex].GraphItem.Y1,
                  sgl.GraphAry[GraphIndex].ForeColor);
  }

  Graph_CalcScaleY(GraphIndex, AxisIndex);

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].TicksMajor)
  {
    HW = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         TicksMajorWidth / 2;
    TY = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         NumbersMinValue;
    F = TY % sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
             NumbersStepMajor;
    if (F != 0)
    {
      TY -= F;
      if (TY < sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
               NumbersMinValue)
        TY += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
              NumbersStepMajor;
    }
    while (TY <= MV)
    {
      DY = sgl.GraphAry[GraphIndex].OrigoY - ((TY -
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
           NumbersMinValue) *
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Scale) /
           10000;
      if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
          NumbersAtOrigo ||
         (TY != sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
                NumbersMinValue))
        GuiLib_FillBox(
           X - sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
           TicksMajorLength + 1,
           DY - HW,
           X,
           DY - HW +
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
           TicksMajorWidth - 1,
           sgl.GraphAry[GraphIndex].ForeColor);
      TY += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
            NumbersStepMajor;
    }
  }

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].TicksMinor)
  {
    HW = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         TicksMinorWidth / 2;
    TY = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         NumbersMinValue;
    F = TY % sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
             NumbersStepMinor;
    if (F != 0)
    {
      TY -= F;
      if (TY < sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
               NumbersMinValue)
        TY += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
              NumbersStepMinor;
    }
    while (TY <= MV)
    {
      DY = sgl.GraphAry[GraphIndex].OrigoY - ((TY -
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
           NumbersMinValue) *
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Scale) /
           10000;
      if ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
          NumbersAtOrigo ||
         (TY != sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
                NumbersMinValue)) &&
         ((!sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
          TicksMajor) ||
         (TY % sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
               NumbersStepMajor != 0)))
        GuiLib_FillBox(
           X - sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
           TicksMinorLength + 1,
           DY - HW,
           X,
           DY - HW +
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
           TicksMinorWidth - 1,
           sgl.GraphAry[GraphIndex].ForeColor);
      TY += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
            NumbersStepMinor;
    }
  }

  if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Numbers)
  {
    memcpy(&sgl.CurItem, &sgl.GraphAry[GraphIndex].GraphItem, sizeof(GuiLib_ItemRec));

    SetCurFont(sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].FontIndex);

    sgl.CurItem.TextPar[0].BitFlags =
       sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].BitFlags;
    sgl.CurItem.FormatFieldWidth =
       sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatFieldWidth;
    sgl.CurItem.FormatDecimals =
       sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatDecimals;
    sgl.CurItem.FormatAlignment =
       sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatAlignment;
    sgl.CurItem.FormatFormat =
       sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatFormat;

    DX = X;
    if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
       TicksMajor)
      DX -= sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         TicksMajorLength;
    DX -= sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
       NumbersOffset;

    TY = sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
       NumbersMinValue;
    F = TY % sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
             NumbersStepMajor;
    if (F != 0)
    {
      TY -= F;
      if (TY < sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
               NumbersMinValue)
        TY += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
              NumbersStepMajor;
    }
    switch (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatAlignment)
    {
      case GuiLib_FORMAT_ALIGNMENT_LEFT:
        Align = GuiLib_ALIGN_LEFT;
        break;
      case GuiLib_FORMAT_ALIGNMENT_CENTER:
        Align = GuiLib_ALIGN_CENTER;
        break;
      case GuiLib_FORMAT_ALIGNMENT_RIGHT:
        Align = GuiLib_ALIGN_RIGHT;
        break;
    }
    while (TY <= MV)
    {
      DY = sgl.GraphAry[GraphIndex].OrigoY - ((TY -
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
           NumbersMinValue) *
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Scale) /
           10000;
      if (sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
          NumbersAtOrigo ||
         (TY != sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
                NumbersMinValue))
      {
        #ifdef GuiConst_FLOAT_SUPPORT_ON
        TDY = TY;
        #endif
        GuiLib_DrawVar(
           DX,
           DY + GuiLib_FONT_MID_Y(ReadByte(sgl.CurFont->BaseLine),
                                  ReadByte(sgl.CurFont->TopLine)),
           sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].FontIndex,
           #ifdef GuiConst_FLOAT_SUPPORT_ON
           &TDY,
           GuiLib_VAR_DOUBLE,
           #else
           &TY,
           GuiLib_VAR_SIGNED_LONG,
           #endif
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatFormat,
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatFieldWidth,
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatAlignment,
           sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].FormatDecimals,
           ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
              BitFlags & GuiLib_BITFLAG_FORMATSHOWSIGN) > 0),
           ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
              BitFlags & GuiLib_BITFLAG_FORMATZEROPADDING) > 0),
           ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
              BitFlags & GuiLib_BITFLAG_FORMATTRAILINGZEROS) > 0),
           ((sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
              BitFlags & GuiLib_BITFLAG_FORMATTHOUSANDSSEP) > 0),
           Align,
           sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].Ps,
           1,   // Transparent
           ((sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].BitFlags &
              GuiLib_BITFLAG_UNDERLINE) > 0),
           0,
           0,
           0,
           0,
           sgl.GraphAry[GraphIndex].GraphItem.ForeColor,
           sgl.GraphAry[GraphIndex].GraphItem.BackColor);
      }
      TY += sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
         NumbersStepMajor;
    }
  }
}

//------------------------------------------------------------------------------
static void Graph_DrawDataPoint(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex,
   GuiConst_INT16U DataIndex,
   GuiConst_INT16S X,
   GuiConst_INT16S Y,
   GuiConst_INT16S LastX,
   GuiConst_INT16S LastY)
{
  GuiConst_INT16S DX1, DY1;
  GuiConst_INT16S DX2, DY2;
  GuiConst_INT16S HW;
  GuiConst_INT16S AY;

  switch (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Representation)
  {
    case GuiLib_GRAPH_DATATYPE_DOT:
      if (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Thickness == 0)
        GuiLib_Circle(
           X, Y,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Width,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].BackColor,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].BackColor);
      else if (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].
               Thickness == 1)
        GuiLib_Circle(
           X, Y,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Width,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].BackColor);
      else
      {
        GuiLib_Circle(
           X, Y,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Width,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor);
        GuiLib_Circle(
           X, Y,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Width-
              sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Thickness,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].BackColor,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].BackColor);
      }
      break;

    case GuiLib_GRAPH_DATATYPE_LINE:
      if (DataIndex ==
          sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataFirst)
        GuiLib_Dot(
           X, Y,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor);
      else
        GuiLib_Line(
           LastX, LastY,
           X, Y,
           sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor);
      break;

    case GuiLib_GRAPH_DATATYPE_BAR:
      AY = sgl.GraphAry[GraphIndex].OrigoY +
           sgl.GraphAry[GraphIndex].GraphAxes[0][GuiLib_GRAPHAXIS_X].Offset;
      DX2 = X + (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Width / 2);
      DX1 = DX2 - sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Width + 1;
      if (DX1 > DX2)
        DX1 = DX2;
      DY1 = AY;
      DY2 = Y;
      if (Y < AY)
        DY1--;
      if (Y != AY)
      {
        if (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Thickness == 0)
        {
          if (!sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].
               BackColorTransparent)
            GuiLib_FillBox(
               DX1, DY1,
               DX2, DY2,
               sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].BackColor);
        }
        else
        {
          OrderCoord(&DX1, &DX2);
          OrderCoord(&DY1, &DY2);
          DrawBorderBox(
             DX1, DY1,
             DX2, DY2,
             sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor,
             sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].BackColor,
             sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].
                BackColorTransparent,
             sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Thickness);
        }
      }
      break;

    case GuiLib_GRAPH_DATATYPE_CROSS:
      HW = sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Width;
      DX1 = X - HW;
      DY1 = Y - HW;
      DX2 = X + HW;
      DY2 = Y + HW;
      GuiLib_Line(
         DX1, Y,
         DX2, Y,
         sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor);
      GuiLib_Line(
         X, DY1,
         X, DY2,
         sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor);
      break;

    case GuiLib_GRAPH_DATATYPE_X:
      HW = sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Width;
      DX1 = X - HW;
      DY1 = Y - HW;
      DX2 = X + HW;
      DY2 = Y + HW;
      GuiLib_Line(
         DX1, DY1,
         DX2, DY2,
         sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor);
      GuiLib_Line(
         DX1, DY2,
         DX2, DY1,
         sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].ForeColor);
      break;
  }
}

//------------------------------------------------------------------------------
static void Graph_DrawDataSet(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex)
{
  GuiConst_INT16S DX = 0, DY = 0;
  GuiConst_INT16S LastDX, LastDY;
  GuiConst_INT32S TX, TY;
  GuiConst_INT16U DataIndex;
  GuiConst_INT16U DataCount;

  Graph_CalcScaleX(GraphIndex,
                   sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX);
  Graph_CalcScaleY(GraphIndex,
                   sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY);

  DataIndex = sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataFirst;
  for (DataCount = 1;
       DataCount <= sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount;
       DataCount++)
  {
    TX =
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr[DataIndex].X;
    TY =
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr[DataIndex].Y;

    LastDX = DX;
    LastDY = DY;
    DX = sgl.GraphAry[GraphIndex].OrigoX + ((TX -
         sgl.GraphAry[GraphIndex].GraphAxes[
         sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX]
         [GuiLib_GRAPHAXIS_X].NumbersMinValue) *
         sgl.GraphAry[GraphIndex].GraphAxes[
         sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX]
         [GuiLib_GRAPHAXIS_X].Scale) / 10000;
    DY = sgl.GraphAry[GraphIndex].OrigoY - ((TY -
         sgl.GraphAry[GraphIndex].GraphAxes[
         sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY]
         [GuiLib_GRAPHAXIS_Y].NumbersMinValue) *
         sgl.GraphAry[GraphIndex].GraphAxes[
         sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY]
         [GuiLib_GRAPHAXIS_Y].Scale) / 10000;

    Graph_DrawDataPoint(
       GraphIndex,
       DataSetIndex,
       DataIndex,
       DX, DY,
       LastDX, LastDY);

    if (DataIndex >= sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount)
      DataIndex = 0;
    else
      DataIndex++;
  }
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_Close(
   GuiConst_INT8U GraphIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);

  sgl.GraphAry[GraphIndex].InUse = GuiLib_GRAPH_STRUCTURE_UNDEF;
  sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X] = 0;
  sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y] = 0;
  sgl.GraphAry[GraphIndex].GraphDataSetCnt = 0;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_AddDataSet(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex,
   GuiConst_INT8U XAxisIndex,
   GuiConst_INT8U YAxisIndex,
   GuiLib_GraphDataPoint *DataPtr,
   GuiConst_INT16U DataSize,
   GuiConst_INT16U DataCount,
   GuiConst_INT16U DataFirst)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((DataSetIndex >= GuiConst_GRAPH_DATASETS_MAX) ||
      (DataSetIndex >= sgl.GraphAry[GraphIndex].GraphDataSetCnt))
    return (0);
  if (DataCount > DataSize)
    return (0);
  if (DataFirst >= DataSize)
    return (0);

  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr = DataPtr;
  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataSize = DataSize;
  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataFirst = DataFirst;
  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount = DataCount;
  if ((XAxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (XAxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X]))
    XAxisIndex = 0;
  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX = XAxisIndex;
  if ((YAxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (YAxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y]))
    YAxisIndex = 0;
  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY = YAxisIndex;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_RemoveDataSet(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((DataSetIndex >= GuiConst_GRAPH_DATASETS_MAX) ||
      (DataSetIndex >= sgl.GraphAry[GraphIndex].GraphDataSetCnt))
    return (0);

  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount = 0;
  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataSize = 0;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_AddDataPoint(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex,
   GuiConst_INT32S X,
   GuiConst_INT32S Y)
{
  GuiConst_INT16U I;

  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((DataSetIndex >= GuiConst_GRAPH_DATASETS_MAX) ||
      (DataSetIndex >= sgl.GraphAry[GraphIndex].GraphDataSetCnt))
    return (0);
  if (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount >=
      sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataSize)
    return (0);

  I = (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataFirst +
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount) %
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataSize;
  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount++;

  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr[I].X = X;
  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr[I].Y = Y;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_ShowDataSet(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((DataSetIndex >= GuiConst_GRAPH_DATASETS_MAX) ||
      (DataSetIndex >= sgl.GraphAry[GraphIndex].GraphDataSetCnt))
    return (0);

  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Visible = 1;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_HideDataSet(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((DataSetIndex >= GuiConst_GRAPH_DATASETS_MAX) ||
      (DataSetIndex >= sgl.GraphAry[GraphIndex].GraphDataSetCnt))
    return (0);

  sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Visible = 0;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_ShowXAxis(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X]))
    return (0);

  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Visible = 1;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_HideXAxis(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X]))
    return (0);

  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].Visible = 0;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_ShowYAxis(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y]))
    return (0);

  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Visible = 1;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_HideYAxis(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y]))
    return (0);

  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].Visible = 0;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_SetXAxisRange(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex,
   GuiConst_INT32S MinValue,
   GuiConst_INT32S MaxValue)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X]))
    return (0);

  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
     NumbersMinValue = MinValue;
  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_X].
     NumbersMaxValue = MaxValue;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_SetYAxisRange(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U AxisIndex,
   GuiConst_INT32S MinValue,
   GuiConst_INT32S MaxValue)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y]))
    return (0);

  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
     NumbersMinValue = MinValue;
  sgl.GraphAry[GraphIndex].GraphAxes[AxisIndex][GuiLib_GRAPHAXIS_Y].
     NumbersMaxValue = MaxValue;

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_ResetXAxisOrigin(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8S AxisIndex)
{
  GuiConst_INT8U AxisIndex1,AxisIndex2;
  GuiConst_INT8U I;

  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if (AxisIndex == -1)
  {
    AxisIndex1 = 0;
    AxisIndex2 = sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X] - 1;
  }
  else if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X]))
    return (0);
  else
  {
    AxisIndex1 = AxisIndex;
    AxisIndex2 = AxisIndex;
  }

  for (I = AxisIndex1; I <= AxisIndex2; I++)
  {
    sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].NumbersMinValue =
       sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].NumbersMinValueOrg;
    sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].NumbersMaxValue =
       sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].NumbersMaxValueOrg;
  }

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_OffsetXAxisOrigin(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8S AxisIndex,
   GuiConst_INT32S Offset)
{
  GuiConst_INT8U AxisIndex1,AxisIndex2;
  GuiConst_INT8U I;

  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if (AxisIndex == -1)
  {
    AxisIndex1 = 0;
    AxisIndex2 = sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X] - 1;
  }
  else if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X]))
    return (0);
  else
  {
    AxisIndex1 = AxisIndex;
    AxisIndex2 = AxisIndex;
  }

  for (I = AxisIndex1; I <= AxisIndex2; I++)
  {
    sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].NumbersMinValue += Offset;
    sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].NumbersMaxValue += Offset;
  }

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_ResetYAxisOrigin(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8S AxisIndex)
{
  GuiConst_INT8U AxisIndex1,AxisIndex2;
  GuiConst_INT8U I;

  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if (AxisIndex == -1)
  {
    AxisIndex1 = 0;
    AxisIndex2 = sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y] - 1;
  }
  else if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y]))
    return (0);
  else
  {
    AxisIndex1 = AxisIndex;
    AxisIndex2 = AxisIndex;
  }

  for (I = AxisIndex1; I <= AxisIndex2; I++)
  {
    sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].NumbersMinValue =
       sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].NumbersMinValueOrg;
    sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].NumbersMaxValue =
       sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].NumbersMaxValueOrg;
  }

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_OffsetYAxisOrigin(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8S AxisIndex,
   GuiConst_INT32S Offset)
{
  GuiConst_INT8U AxisIndex1,AxisIndex2;
  GuiConst_INT8U I;

  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if (AxisIndex == -1)
  {
    AxisIndex1 = 0;
    AxisIndex2 = sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y] - 1;
  }
  else if ((AxisIndex >= GuiConst_GRAPH_AXES_MAX) ||
      (AxisIndex >= sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y]))
    return (0);
  else
  {
    AxisIndex1 = AxisIndex;
    AxisIndex2 = AxisIndex;
  }

  for (I = AxisIndex1; I <= AxisIndex2; I++)
  {
    sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].NumbersMinValue += Offset;
    sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].NumbersMaxValue += Offset;
  }

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_Redraw(
   GuiConst_INT8U GraphIndex)
{
  GuiConst_INT16S I;

  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  Graph_SetClipping(GraphIndex);
#endif

  GuiLib_Graph_DrawAxes(GraphIndex);

  for (I = sgl.GraphAry[GraphIndex].GraphDataSetCnt - 1; I >= 0; I--)
    GuiLib_Graph_DrawDataSet(GraphIndex, I);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  Graph_ResetClipping();
#endif

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_DrawAxes(
   GuiConst_INT8U GraphIndex)
{
  GuiConst_INT16S I;

  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  Graph_SetClipping(GraphIndex);
#endif

  if (!(sgl.GraphAry[GraphIndex].GraphItem.TextPar[0].BitFlags &
        GuiLib_BITFLAG_TRANSPARENT))
    GuiLib_FillBox(sgl.GraphAry[GraphIndex].GraphItem.X1,
                   sgl.GraphAry[GraphIndex].GraphItem.Y1,
                   sgl.GraphAry[GraphIndex].GraphItem.X2,
                   sgl.GraphAry[GraphIndex].GraphItem.Y2,
                   sgl.GraphAry[GraphIndex].GraphItem.BackColor);

  for (I = sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_X] - 1;
       I >= 0; I--)
    if (sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_X].Visible)
      Graph_DrawXAxis(GraphIndex, I);

  for (I = sgl.GraphAry[GraphIndex].GraphAxesCnt[GuiLib_GRAPHAXIS_Y] - 1;
       I >= 0; I--)
    if (sgl.GraphAry[GraphIndex].GraphAxes[I][GuiLib_GRAPHAXIS_Y].Visible)
      Graph_DrawYAxis(GraphIndex, I);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  Graph_ResetClipping();
#endif

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_DrawDataSet(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex)
{
  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((DataSetIndex >= GuiConst_GRAPH_DATASETS_MAX) ||
      (DataSetIndex >= sgl.GraphAry[GraphIndex].GraphDataSetCnt))
    return (0);
  if (!sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Visible)
    return (0);
  if (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataSize == 0)
    return (0);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  Graph_SetClipping(GraphIndex);
#endif

  Graph_DrawDataSet(GraphIndex, DataSetIndex);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  Graph_ResetClipping();
#endif

  return (1);
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_Graph_DrawDataPoint(
   GuiConst_INT8U GraphIndex,
   GuiConst_INT8U DataSetIndex,
   GuiConst_INT16U DataIndex)
{
  GuiConst_INT16S Y;
  GuiConst_INT16S DX, DY;
  GuiConst_INT16S LastDX, LastDY;
  GuiConst_INT32S TX, TY;

  if ((GraphIndex >= GuiConst_GRAPH_MAX) ||
      (sgl.GraphAry[GraphIndex].InUse != GuiLib_GRAPH_STRUCTURE_USED))
    return (0);
  if ((DataSetIndex >= GuiConst_GRAPH_DATASETS_MAX) ||
      (DataSetIndex >= sgl.GraphAry[GraphIndex].GraphDataSetCnt))
    return (0);
  if (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataSize == 0)
    return (0);
  if (!sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Visible)
    return (0);
  if (DataIndex >= sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount)
    return (0);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  Graph_SetClipping(GraphIndex);
#endif

  Graph_CalcScaleX(GraphIndex,
                   sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX);
  Graph_CalcScaleY(GraphIndex,
                   sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY);

  TX = sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr[DataIndex].X;
  TY = sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr[DataIndex].Y;
  DX = sgl.GraphAry[GraphIndex].OrigoX + ((TX -
       sgl.GraphAry[GraphIndex].GraphAxes[
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX]
       [GuiLib_GRAPHAXIS_X].NumbersMinValue) *
       sgl.GraphAry[GraphIndex].GraphAxes[
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX]
       [GuiLib_GRAPHAXIS_X].Scale) / 10000;
  DY = sgl.GraphAry[GraphIndex].OrigoY - ((TY -
       sgl.GraphAry[GraphIndex].GraphAxes[
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY]
       [GuiLib_GRAPHAXIS_Y].NumbersMinValue) *
       sgl.GraphAry[GraphIndex].GraphAxes[
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY]
       [GuiLib_GRAPHAXIS_Y].Scale) / 10000;
  if (sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].Representation ==
      GuiLib_GRAPH_DATATYPE_LINE)
  {
    if (DataIndex == 0)
      DataIndex = sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataCount - 1;
    else
      DataIndex--;

    TX =
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr[DataIndex].X;
    TY =
       sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].DataPtr[DataIndex].Y;
    LastDX = sgl.GraphAry[GraphIndex].OrigoX + ((TX -
            sgl.GraphAry[GraphIndex].GraphAxes[
            sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX]
            [GuiLib_GRAPHAXIS_X].NumbersMinValue) *
            sgl.GraphAry[GraphIndex].GraphAxes[
            sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexX]
            [GuiLib_GRAPHAXIS_X].Scale) / 10000;
    LastDY = sgl.GraphAry[GraphIndex].OrigoY - ((TY -
             sgl.GraphAry[GraphIndex].GraphAxes[
             sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY]
             [GuiLib_GRAPHAXIS_Y].NumbersMinValue) *
             sgl.GraphAry[GraphIndex].GraphAxes[
             sgl.GraphAry[GraphIndex].GraphDataSets[DataSetIndex].AxisIndexY]
             [GuiLib_GRAPHAXIS_Y].Scale) / 10000;
  }
  else
  {
    LastDX = DX;
    LastDY = DY;
  }

  Graph_DrawDataPoint(
     GraphIndex,
     DataSetIndex,
     DataIndex,
     DX, DY,
     LastDX, LastDY);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  Graph_ResetClipping();
#endif

  return (1);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#endif // GuiConst_ITEM_GRAPH_INUSE

#ifdef GuiConst_ITEM_GRAPHICS_LAYER_FILTER_INUSE
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static GuiConst_INT16S IndexOfGraphicsLayer(
   GuiConst_INT16S GraphicsLayerIndex)
{
  GuiConst_INT16S I;

  if (GraphicsLayerIndex == GuiLib_GRAPHICS_LAYER_BASE)
    return(GuiLib_GRAPHICS_LAYER_BASE);
  else if (GraphicsLayerIndex == GuiLib_GRAPHICS_LAYER_PREVIOUS)
  {
    if (sgl.GraphicsLayerLifoCnt <= 1)
      return(GuiLib_GRAPHICS_LAYER_BASE);
    else
      return(sgl.GraphicsLayerLifo[sgl.GraphicsLayerLifoCnt - 2]);
  }
  else if (GraphicsLayerIndex == GuiLib_GRAPHICS_LAYER_CURRENT)
  {
    if (sgl.GraphicsLayerLifoCnt > 0)
      return(sgl.GraphicsLayerLifo[sgl.GraphicsLayerLifoCnt - 1]);
    else
      return(GuiLib_GRAPHICS_LAYER_BASE);
  }
  else if (GraphicsLayerIndex < 0)
    return(GuiLib_GRAPHICS_LAYER_BASE);
  else if (sgl.GraphicsLayerLifoCnt <= 1)
    return(GuiLib_GRAPHICS_LAYER_BASE);
  for (I = 0; I < sgl.GraphicsLayerLifoCnt; I++)
    if (sgl.GraphicsLayerLifo[I] == GraphicsLayerIndex)
      return(GraphicsLayerIndex);
  return(GuiLib_GRAPHICS_LAYER_BASE);
}

//------------------------------------------------------------------------------
static GuiConst_INT8U GraphicsLayer_Push(
   GuiConst_INT8U GraphicsLayerIndex)
{
  GuiConst_INT16S I;

  if (GraphicsLayerIndex >= GuiConst_GRAPHICS_LAYER_MAX)
    return(0);
  if (sgl.GraphicsLayerList[GraphicsLayerIndex].InUse != GuiLib_GRAPHICS_LAYER_USED)
    return(0);
  if (sgl.GraphicsLayerLifoCnt == GuiConst_GRAPHICS_LAYER_MAX)
    return(0);
  for (I = 0; I < sgl.GraphicsLayerLifoCnt; I++)
    if (sgl.GraphicsLayerLifo[I] == GraphicsLayerIndex)
      return(0);

  sgl.GraphicsLayerLifo[sgl.GraphicsLayerLifoCnt] = GraphicsLayerIndex;
  sgl.GraphicsLayerLifoCnt++;
  sgl.GraphicsLayerList[GraphicsLayerIndex].BaseAddress =
   &sgl.LayerBuf[(GuiConst_INT32U)ReadWord(
   GuiStruct_GraphicsLayerOfs[GraphicsLayerIndex])];

  sgl.CurLayerBufPtr = sgl.GraphicsLayerList[GraphicsLayerIndex].BaseAddress;
  sgl.CurLayerLineSize = sgl.GraphicsLayerList[GraphicsLayerIndex].LineSize;
  sgl.CurLayerWidth = sgl.GraphicsLayerList[GraphicsLayerIndex].Width;
  sgl.CurLayerHeight = sgl.GraphicsLayerList[GraphicsLayerIndex].Height;
  sgl.CurLayerBytes =
     sgl.GraphicsLayerList[GraphicsLayerIndex].Height *
     sgl.GraphicsLayerList[GraphicsLayerIndex].LineSize;
  sgl.BaseLayerDrawing = 0;

  return(1);
}

//------------------------------------------------------------------------------
static GuiConst_INT8U GraphicsLayer_Pop(
   GuiConst_INT16S GraphicsLayerIndex)
{
  GuiConst_INT16S I;

  if (GraphicsLayerIndex == GuiLib_GRAPHICS_LAYER_BASE)
    sgl.GraphicsLayerLifoCnt = 0;
  else if ((GraphicsLayerIndex == GuiLib_GRAPHICS_LAYER_PREVIOUS) &&
           (sgl.GraphicsLayerLifoCnt > 0))
  {
    sgl.GraphicsLayerLifoCnt--;
    GraphicsLayerIndex = sgl.GraphicsLayerLifo[sgl.GraphicsLayerLifoCnt - 1];
  }
  else if (GraphicsLayerIndex < 0)
    return(0);
  else if (sgl.GraphicsLayerLifoCnt <= 1)
    return(0);
  else
  {
    for (I = sgl.GraphicsLayerLifoCnt - 2; I >= 0; I--)
      if (sgl.GraphicsLayerLifo[I] == GraphicsLayerIndex)
      {
        sgl.GraphicsLayerLifoCnt = I + 1;
        break;
      }
    if (I == -1)
      return(0);
  }

  if (sgl.GraphicsLayerLifoCnt == 0)
    ResetLayerBufPtr();
  else
  {
    sgl.CurLayerBufPtr = sgl.GraphicsLayerList[GraphicsLayerIndex].BaseAddress;
    sgl.CurLayerLineSize = sgl.GraphicsLayerList[GraphicsLayerIndex].LineSize;
    sgl.CurLayerWidth = sgl.GraphicsLayerList[GraphicsLayerIndex].Width;
    sgl.CurLayerHeight = sgl.GraphicsLayerList[GraphicsLayerIndex].Height;
    sgl.CurLayerBytes =
       sgl.GraphicsLayerList[GraphicsLayerIndex].Height *
       sgl.GraphicsLayerList[GraphicsLayerIndex].LineSize;
    sgl.BaseLayerDrawing = 0;
  }

  return(1);
}

//------------------------------------------------------------------------------
static void GraphicsLayer_Copy(
   GuiConst_INT8U *DestAddress,
   GuiConst_INT16U DestLineSize,
   GuiConst_INT16S DestX,
   GuiConst_INT16S DestY,
   GuiConst_INT8U *SourceAddress,
   GuiConst_INT16U SourceLineSize,
   GuiConst_INT16S SourceX,
   GuiConst_INT16S SourceY,
   GuiConst_INT16U Width,
   GuiConst_INT16U Height)
{
  GuiConst_INT16S LineSize;

  SourceAddress +=
     SourceY * SourceLineSize + GuiConst_PIXEL_BYTE_SIZE * SourceX;
  DestAddress += DestY * DestLineSize + GuiConst_PIXEL_BYTE_SIZE * DestX;
  LineSize = GuiConst_PIXEL_BYTE_SIZE * Width;
  while (Height > 0)
  {
    memcpy(DestAddress, SourceAddress, LineSize);
    SourceAddress += SourceLineSize;
    DestAddress += DestLineSize;
    Height--;
  }
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_GraphicsFilter_Init(
   GuiConst_INT8U GraphicsFilterIndex,
   void (*FilterFuncPtr)
     (GuiConst_INT8U *DestAddress,
      GuiConst_INT16U DestLineSize,
      GuiConst_INT8U *SourceAddress,
      GuiConst_INT16U SourceLineSize,
      GuiConst_INT16U Width,
      GuiConst_INT16U Height,
      GuiConst_INT32S FilterPars[10]))
{
  if (GraphicsFilterIndex >= GuiConst_GRAPHICS_FILTER_MAX)
    return (0);

  sgl.GraphicsFilterList[GraphicsFilterIndex].GraphicsFilterFunc = FilterFuncPtr;

  return (1);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#endif // GuiConst_ITEM_GRAPHICS_LAYER_FILTER_INUSE

#ifdef GuiConst_TEXTBOX_FIELDS_ON
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GuiConst_INT16S *TextBox_Scroll_GetPosRec(GuiConst_INT8U TextBoxIndex)
{
  GuiConst_INT16S I;
  GuiConst_INT16S *result = NULL;

  for (I=0;I<GuiConst_TEXTBOX_FIELDS_MAX;I++)
  {
    if (sgl.TextBoxScrollPositions[I].index == TextBoxIndex)
    {
      result = &sgl.TextBoxScrollPositions[I].pos;
      break;
    }
  }

  return result;
}
//------------------------------------------------------------------------------
static GuiConst_INT16S TextBox_Scroll_CalcEndPos(
   GuiLib_ItemRec PrefixLocate *TextBoxItem,
   GuiConst_INT8U PerLine)
{
  GuiConst_INT16S H;

  H = TextBoxItem->Y2 -
      TextBoxItem->Y1 + 1;
  if (PerLine)
    return (TextBoxItem->CompPars.CompTextBox.LineDist *
       (TextBoxItem->CompPars.CompTextBox.Lines -
       (H / TextBoxItem->CompPars.CompTextBox.LineDist)));
  else
    return (TextBoxItem->CompPars.CompTextBox.Lines *
       TextBoxItem->CompPars.CompTextBox.LineDist - H);
}
#endif // GuiConst_TEXTBOX_FIELDS_ON

//------------------------------------------------------------------------------
static GuiConst_INT8U TextBox_Scroll_To(
   GuiConst_INT8U TextBoxIndex,
   GuiConst_INT16S NewPos,
   GuiConst_INT8U PerLine,
   GuiConst_INT8U AbsoluteMove)
{
#ifdef GuiConst_TEXTBOX_FIELDS_ON
  GuiLib_ItemRec PrefixLocate *TextBoxItem;
  GuiConst_INT16S TextBox;
  GuiConst_INT16S PrefixLocate *ScrollPos;

  TextBox = AutoRedraw_GetTextBox(TextBoxIndex, -1);

  if (TextBox == -1)
    return (0);

  TextBoxItem = AutoRedraw_GetItem(TextBox);

  if (TextBoxItem == NULL)
    return (0);
  else
  {
    ScrollPos = TextBox_Scroll_GetPosRec(TextBoxIndex);

    if (ScrollPos == NULL)
      return (0);

    if (PerLine)
      NewPos *= TextBoxItem->CompPars.CompTextBox.LineDist;

    switch (AbsoluteMove)
    {
      case 0:
        *ScrollPos += NewPos;
        break;

      case 1:
        *ScrollPos = NewPos;
        break;

      case 2:
        *ScrollPos = TextBox_Scroll_CalcEndPos(TextBoxItem, PerLine);
        break;
    }

    TextBoxItem->CompPars.CompTextBox.ScrollPos = *ScrollPos;

    memcpy(&sgl.CurItem, TextBoxItem, sizeof(GuiLib_ItemRec));

    GuiDisplay_Lock();

    sgl.DisplayLevel = 0;
    sgl.SwapColors = 0;
    DrawItem(GuiLib_COL_INVERT_OFF);

    GuiDisplay_Unlock();
    return (1);
  }
#else
  gl.Dummy1_8U = TextBoxIndex;   // To avoid compiler warning
  gl.Dummy1_16S = NewPos;   // To avoid compiler warning
  gl.Dummy2_8U = PerLine;   // To avoid compiler warning
  gl.Dummy3_8U = AbsoluteMove;   // To avoid compiler warning
  return (0);
#endif
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_Up(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_To(TextBoxIndex, -1, 1, 0));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_Down(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_To(TextBoxIndex, 1, 1, 0));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_Home(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_To(TextBoxIndex, 0, 1, 1));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_End(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_To(TextBoxIndex, 0, 1, 2));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_To_Line(
   GuiConst_INT8U TextBoxIndex,
   GuiConst_INT16S NewLine)
{
  return (TextBox_Scroll_To(TextBoxIndex, NewLine, 1, 1));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_Up_Pixel(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_To(TextBoxIndex, -1, 0, 0));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_Down_Pixel(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_To(TextBoxIndex, 1, 0, 0));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_Home_Pixel(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_To(TextBoxIndex, 0, 0, 1));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_End_Pixel(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_To(TextBoxIndex, 0, 0, 2));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_To_PixelLine(
   GuiConst_INT8U TextBoxIndex,
   GuiConst_INT16S NewPixelLine)
{
  return (TextBox_Scroll_To(TextBoxIndex, NewPixelLine, 0, 1));
}

//------------------------------------------------------------------------------
static GuiConst_INT8U TextBox_Scroll_Get_Pos(
   GuiConst_INT8U TextBoxIndex,
   GuiConst_INT8U PerLine)
{
#ifdef GuiConst_TEXTBOX_FIELDS_ON
  GuiConst_INT16S P;
  GuiLib_ItemRec PrefixLocate*TextBoxItem;
  GuiConst_INT16S TextBox;
  GuiConst_INT16S PrefixLocate *ScrollPos;

  TextBox = AutoRedraw_GetTextBox(TextBoxIndex, -1);

  if (TextBox == -1)
    return (GuiLib_TEXTBOX_SCROLL_ILLEGAL_NDX);

  TextBoxItem = AutoRedraw_GetItem(TextBox);

  if (TextBoxItem == NULL)
    return (GuiLib_TEXTBOX_SCROLL_ILLEGAL_NDX);

  ScrollPos = TextBox_Scroll_GetPosRec(TextBoxIndex);

  if (ScrollPos == NULL)
    return (GuiLib_TEXTBOX_SCROLL_ILLEGAL_NDX);

  P = TextBox_Scroll_CalcEndPos(TextBoxItem, PerLine);
  if (*ScrollPos == 0)
    return (GuiLib_TEXTBOX_SCROLL_AT_HOME);
  else if (*ScrollPos == P)
    return (GuiLib_TEXTBOX_SCROLL_AT_END);
  else if (*ScrollPos < 0)
    return (GuiLib_TEXTBOX_SCROLL_ABOVE_HOME);
  else if (*ScrollPos > P)
    return (GuiLib_TEXTBOX_SCROLL_BELOW_END);
  else
    return (GuiLib_TEXTBOX_SCROLL_INSIDE_BLOCK);

#else
  gl.Dummy1_8U = TextBoxIndex;   // To avoid compiler warning
  gl.Dummy2_8U = PerLine;   // To avoid compiler warning
  return (GuiLib_TEXTBOX_SCROLL_ILLEGAL_NDX);
#endif
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_Get_Pos(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_Get_Pos(TextBoxIndex, 1));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_Get_Pos_Pixel(
   GuiConst_INT8U TextBoxIndex)
{
  return (TextBox_Scroll_Get_Pos(TextBoxIndex, 0));
}

//------------------------------------------------------------------------------
GuiConst_INT8U GuiLib_TextBox_Scroll_FitsInside(
   GuiConst_INT8U TextBoxIndex)
{
#ifdef GuiConst_TEXTBOX_FIELDS_ON
  GuiLib_ItemRec PrefixLocate *TextBoxItem;
  GuiConst_INT16S TextBox;
  GuiConst_INT16S PrefixLocate *ScrollPos;

  TextBox = AutoRedraw_GetTextBox(TextBoxIndex, -1);

  if (TextBox == -1)
    return (0);

  TextBoxItem = AutoRedraw_GetItem(TextBox);

  if (TextBoxItem == NULL)
    return (0);

  return (TextBox_Scroll_CalcEndPos(TextBoxItem, 0) < 0);
#else
  gl.Dummy1_8U = TextBoxIndex;   // To avoid compiler warning
  return (0);
#endif
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GuiConst_INTCOLOR GuiLib_SetButtonDisabledColor(GuiConst_INTCOLOR PixelColor)
{
#ifdef GuiConst_ITEM_BUTTON_INUSE
  sgl.ButtonColorOverride = GuiLib_TRUE;
  sgl.DisabledButtonColor = PixelColor;
#endif

  return PixelColor;
}
//------------------------------------------------------------------------------