Статьи

Важность допроса


Один из моих комментариев о моем последнем шаблоне
дизайна блога
, «Новая одежда и улов 22
» Императора, заключался в том, что
«одна из самых ценных вещей, которые предлагают эти шаблоны, — это словарный запас. Они дают что-то имя. , что является важным моментом, который я думаю, я пропустил. Идея состоит в том, что если у кого-то есть имя, это то, о чем вы можете легко общаться. Например, проще сказать «Я использовал Singleton», а не «Я создал этот класс, где есть только один экземпляр, и этот экземпляр доступен всем другим классам в приложении»

Я часто думал, что наименование в целом имеет решающее значение для написания хорошего программного обеспечения, и что в какой-то момент я обязательно напишу (или два) блог на эту тему. На данный момент достаточно сказать, что когда вы видите метод или класс с неправильным названием, будьте храбрыми, прыгайте и
нажимайте правую кнопку мыши , «
Перефакторинг» и «
Переименовывать …» пункты меню
1 , но помните, что хитрость заключается в поиске наиболее значимого имени.

Читая мой предыдущий блог, у вас может сложиться впечатление, что я против паттернов. Это не может быть далеким от истины, хотя я и анти-паттерны, я полностью про-паттерны, будь то прямые шаблоны Gang Of Four, паттерны корпоративной прикладной архитектуры Мартина Фаулера или любые другие паттерны, но я Также думаю, что правильное использование шаблонов также важно.

Один из моментов, который следует сделать в отношении шаблонов GOF, заключается в том, что их можно ранжировать с точки зрения полезности, важности и популярности. Например, практически каждый разработчик знает о
Singleton (это потому, что он самый простой?), И, если вы использовали Spring, вы столкнетесь со
стратегией, Если вы не используете Spring, то я подозреваю, что вы с большей вероятностью узнаете о шаблонах создания:
Абстрактная фабрика ,
Фабричный метод и
Строитель . Если вы выполнили некоторую работу с JEE (он же J2EE), вы наверняка видели, как
Facade используется в качестве интерфейса к EJB2.

Кроме того, вы можете использовать или использовать
Observer для информирования групп объектов об изменении состояния одного объекта, или использовать
Template для определения скелетного алгоритма, но есть такие шаблоны, которые вам не часто приходится использовать. Возьми
памятьбольшинство разработчиков сталкивались с этим в форме Serializable, но я не могу вспомнить, что мне пришлось реализовывать его самостоятельно, кроме как в упражнении по изучению
Memento, а затем есть
State Machine .

Впервые я увидел эту модель в 1989 году, за пять лет до того, как GOF опубликовал свою книгу. Он использовался в эмуляторе VT Terminal, написанном на «С» в Windows 2.1, как часть ныне несуществующего проекта CityDesk, созданного несуществующей компанией Apricot Computers.
State Machine очень полезен для разбора входящих байтовых потоков по байтам за раз и определения действий, которые необходимо предпринять, и просто для потомков ниже представлен фрагмент кода CityDesk: это не красиво, это не Java, это не ОО, но это
конечный автомат и это предшествует GOF.

Тем не менее, возвращаясь на ходу … хотя State Machine действительно полезен для выполнения описанных выше видов работ, теперь существуют более современные способы обработки байтовых потоков, которые в случае Java предоставляются в String, Streams и связанных классах SDK. такие как Pattern, Matcher и т. д. Итак,
State Machine становится более устаревшей или есть ли другие действительно хорошие применения для нее?

В заключение этого блога, я думаю, я должен повторить, что я про-шаблоны: шаблон, используемый в соответствующем месте, обеспечивает очень полезное решение распространенной проблемы, но я думаю, что они должны время от времени подвергаться сомнению. Шаблоны GOF существуют уже давно: можно ли их улучшить? Они все еще актуальны сегодня, как они были, когда книга была написана? Опрашивать о вещах — это важный навык. Если вы не будете задавать вопросы, вы просто станете программистом
Cargo Cult .

Вы действительно не хотите видеть это

/*****************************************************************************/
/*                                                                           */
/* Program / Project Name      Vt320 Terminal Emulation Package              */
/*                                                                           */
/* Module Name                 Vt220.c                                       */
/*                                                                           */
/* Description     Much changed but still compatible version of the earlier  */
/*                 version of the Term220 file                               */
/*  Contains the Vt320/220/100/52 State machine functions                    */
/*                                                                           */
/* Procedures Included  EmulateVT100  CheckForEscSequence  VT100Cntl         */
/*  VT100Esc  VT100Private                                                   */
/*                                                                           */
/* Updates       None                                                        */
/*     MID 11.07.1989 2.00.02   Cursor up and down now checks       */
/*            for cursor movement beyond the     */
/*            screen bounds.         */
/*                       */
/* Va 2.00.05 4:35pm 14/7/89                                                 */
/* Mod to clear the Status line of data if in HostWrite mode                 */
/*                       */
/* Vb 2.00.01 9:40am 22/8/89  Mods around line 547 on EndRow resetting     */
/*                       */
/* Vb 2.00.01 10:20am 22/8/89                                               */
/*   - Mod to new line action so that if the scroll region is smaller than   */
/*   the screen then the cursor cannot LF past the bottom of the screen      */
/*                       */
/*****************************************************************************/

/************************************************************************
*
        EmulateVT220 - VT220 Emulator
*
*************************************************************************/



#include <windows.h>
#include <lcdcomms.h>
#include <lcdwcom.h>
#include <cdk.h>

#include <lcdprod.h>
#include <lcdctrl.h>
#include <sc_print.h>
#include <term.h>
#include <term320.h>
#include <Winstuff.h>
#include <lcdtiff.h>    /* Imports for grafs */
#include <funcdecs.h>

#include "term220.h"
#include "Scroll.h"

#include "externs.h"



VOID    EmulateVT100 (lpCharBuff, Cnt)
LPSTR   lpCharBuff;
int     Cnt;
{
#ifdef TERM320
  extern BOOL tWatch;
#endif
  extern BOOL DisplayControls;
  extern UTC utc;
   BYTE   c;

   while (Cnt--)    /* For all the characters in the buffer loop around and sort them out */
   {
        c = *lpCharBuff++;  /* make c the next char to process */



      /* Allow the VT320 double height stuff to work
       * in the clearing screen bit
       */
      if(DecDWLHoldOff)
      {
      DWLReset(ScreenVars.CurrentRow,ScreenVars.EndRow);
         DecDWLHoldOff = FALSE;
      }

    if(utc.Mode != UTC_NORMAL)
        ProcessTheMessage(c); /* call this if we're in Unit trust mode */
    else
     {

      if(DisplayControls)    /* for control characters display every thing */
         {
         BufferCharacters(c);
         continue;
         }
    if(PrintController(c))  /* sort out any printing we may be doing */
      continue;


       switch (c)  /*  Check for control characters  */
        {
        case NULL:    /*  11.07.1989  MID  2.00.02  */
          break;    /* this is here to stop the output th the screen when print controller is on */
        case 11:
        case '\n':      /* NEWLINE */
        AddToScrollScreen(ScreenVars.CurrentRow);    /* put the line in the scrolling screen region */
           AddLineAutoPrint(c);    /* put this line in the file */
        if (fCaptureLine)
            CaptureLine ();
            if (ScreenVars.CurrentRow == ScreenVars.ScrollBottom)
         {
            //ScrollVEx (&ScreenImage[0][0],
             //      &AttributeMap[0][0],
             //    NULL,
             //      (LPSCREENVARS)&ScreenVars,
             //      hWndMain,
             //    ScreenVars.ScrollTop,
             //    ScreenVars.ScrollBottom,
             //    1,
               //      (BUTTONDATA FAR *)&bd,
             //    (LPFONTVARS)&FontVars);
            ScrollVEx (
                   hWndMain,
                 ScreenVars.ScrollTop,
                 ScreenVars.ScrollBottom,
                 1);

          DWLScroll(ScreenVars.ScrollTop,ScreenVars.ScrollBottom,1);
         }
        else if(ScreenVars.CurrentRow < ScreenVars.EndRow)  /* RH 22/8/89 Vb 2.0.01 */
            ++ScreenVars.CurrentRow;

        /*  IF SEQUENCE LNM IS ACTIVE MOVE CURSOR TO COL 0  */
        if (fLFCR)
            ScreenVars.CurrentCol = 0;
             faNewLine = FALSE;
          break;

            case '\07':     /* BELL */
          MessageBeep (0);
        break;

            case '\r':      /* CARRIAGE RETURN */
        ScreenVars.CurrentCol = 0;
        faNewLine = FALSE;
                break;

            case '\b':      /* BACKSPACE */
          if (ScreenVars.CurrentCol)
          --ScreenVars.CurrentCol;
                break;

            case '\t':      /* TAB */
            if (ScreenVars.CurrentCol < ScreenVars.EndCol)
         {
            for (++ScreenVars.CurrentCol; ScreenVars.CurrentCol <= ScreenVars.EndCol; ScreenVars.CurrentCol++)
             {
              if (ScreenVars.TabStops[ScreenVars.CurrentCol])
                break;
             }
         }
                break;

            case 0x7f:      /* Ignore delete character */
          if(bd.Terminal.TermOptions.MapBackSpaceToDel && ScreenVars.CurrentCol)
            --ScreenVars.CurrentCol;
                break;

        case 5:  /* ENQ  */
         if(tWatch)
           SendDataBlock(bd.Data2,lstrlen(bd.Data2),FALSE);
            SendAnswerBack();
        break;

        case SO: /* move G1 on to GL */
            CurrentSet = &CharacterSet1;
            break;

        case SI:  /* move G0 into GL */
            CurrentSet = &CharacterSet0;
            break;

      default:   /*  Check for Escape sequences  */
        CheckForEscSequence (c);
            break;
        }
    }
    } 
}

/************************************************************************
*  This function checks for escape sequences. If one is found it is
   processed. If not then it is a normal character and is displayed.
*
*************************************************************************/

VOID CheckForEscSequence (c)

BYTE    c;

{
  extern BOOL DecUKKeyBoard;
   extern BYTE PoundSign;

    switch (State)
   {
        case NORMAL:
        /*  CHANGE STATE TO LOOK OF ESCAPE SEQUENCE IF ESCAPE RECEIVED  */
      if (c == ESC)
            State = ESCED;
                    /* check for an 8 bit escape sequence */
        else if(bd.Terminal.TermOptions.Bits87 && ((c >= 0x80)&&(c <= 0x9f)))
          {
        State = ESCED;      /* c - 0x40 puts the char back into the correct range */
            c -= (BYTE)0x40;
        CheckForEscSequence(c);  /* ie. 0x9b - 0x40 = 0x5b or'['. hence respond to an ESC [ call */
          }
        /*  NORMAL CHARACTER THEN PUT INTO SCREEN BUFFER  */
        else if (c >= 32)
         {
            if(DecUKKeyBoard && (c == PoundSign))
               c = 0x9c;
           BufferCharacters (c);
         }
           break;

    case POSS_DECSTR:  /* a possible soft reset is on the way */
      if(c == ESC)
        {
             State = ESCED;
        break;
        }
      else if((c == 'p') && (bd.Terminal.TermOptions.TermType != CDK_VT100))  
           DecStr();
      if(c != 'p')
        State = SQU_ERROR;
      else
          State = NORMAL;
        break;

        case ESCED:
      if(c == ESC)
        {
             State = ESCED;
        break;
        }
      else if (c == '(')
               State = CHARSET_G0;
          else if (c == ')')
               State = CHARSET_G1;
          else if (c == 'P')
          {
           ClrParam();
           State = PARAMS;
           Pnum2 = 0;
          }
        else  /* CONTROL SEQUENCE INTRODUCER */
            if (c == '[')
             {
              ClrParam ();
              State = PARAMS;
             }
        else /* INTERMEDIATE CHARACTERS */
            if (c > 0x20 && c <= 0x2f)
              State = ESCSQU;
        else if(c == ' ')  /* check for an ESC' ' input to switch mode */
        State = CONTROLXMIT;
        else if (c >= 0x30 && c <= 0x7e)
              VT100Esc (c);
        else
               State = SQU_ERROR;
         break;

      case ESCSQU:
      if(c == ESC)
        {
             State = ESCED;
        break;
        }
      else if (c >= 0x30 && c <= 0x7e)
              VT100Esc (c);
            break;

       case PARAMS: /* PARAMETER CHARACTERS */      /*NEWBIT*/
          if (Pnum == 0 && c >= 0x3c && c <= 0x3f)
              fPrivate = TRUE;
          else if (c == IMMED)
              State = NORMAL;
        else if ((c == '|')&&(Pnum2 < NO2PARAMS))
         {
          FlagDCS = TRUE;
          Param2[Pnum2++] = c;
         }
        else if ((FlagDCS == TRUE) && (c == 0x1b))
             FlagDCS = FALSE;
           else if((c == 0x22) && (Pnum2 < NO2PARAMS))
            Param2[Pnum2] = c;
        else if (c >= '0' && c <= '9')
             {
              if (Pnum2 < NO2PARAMS)
              Param2[Pnum2++] = c;
        if(Pnum < NOPARAMS)
          {
               Param[Pnum] *= 10;
                 Param[Pnum] += (c - '0');
          }
             }
            else if (c == ';')
             {
               if(++Pnum > (NOPARAMS - 1))
                     State = NORMAL;
          if(++Pnum2 < NO2PARAMS)
                Param2[Pnum2] = c;
             }
        else if ((FlagDCS == TRUE)&&(Pnum2 < NO2PARAMS))
           Param2[Pnum2++] = c;
        else if(c == '$')  /* a dollar sign for the status line Escape sequences */
        State = STATUSLINE_ESCSEQ;
        else if(c == '!')        
        State = POSS_DECSTR;     /* a possible soft reset is on the way */
      else if(c == ESC)
        State = ESCED;      /* an unterminated esc sequence */
        else
             {
            if (fPrivate || (c >= 0x70 && c <= 0x7e))
                VT100Private (c);
                else
                    VT100Cntl (c);
               fPrivate = FALSE;
              }
     
             break;

      case CHARSET_G1:
      if(c == ESC)
        {
             State = ESCED;
        break;
        }
        else if (c == '0')
            CharacterSet1 = TRUE;   /*  move Dec Graphics in to G1 */
      else              /* this covers A and B */
            CharacterSet1 = FALSE;  /*  ASCII into G1 */

          State = NORMAL;
        break;   

    case CHARSET_G0:
      if(c == ESC)
        {
             State = ESCED;
        break;
        }
          else if (c == '0')
            CharacterSet0 = TRUE;   /*  Graphics  */
      else              /* this covers A and B */
            CharacterSet0 = FALSE;  /*  ASCII  */

          State = NORMAL;
          break;

    case STATUSLINE_ESCSEQ:    /* act on a status line esacpe sequence */
      if(c == ESC)
        {
             State = ESCED;
        break;
        }
        VT100Cntl(c);
        break;
    case CONTROLXMIT:  /* a possible change of control code bits is on the way */
      if(c == ESC)
        {
             State = ESCED;
        break;
        }
        SelectTransmissionStyle(c);
        break;
    case SQU_ERROR:
      if(c == ESC)
        State = ESCED;
      else if ((c >= '@') && (c < 0x7f))
        State = NORMAL;
       
      break;
    default:
      if(c == ESC)
             State = ESCED;
      else
              State = NORMAL;
        break;
    }
}












/************************************************************************
*
        VT100Cntl - Check for VT100 Control escape sequences
*
*************************************************************************/

VOID    VT100Cntl (c)
BYTE    c;
{
#ifdef TERM320
   extern BOOL tWatch;
#endif
    int    lines;



  State = NORMAL;
    switch (c)
     {
        /*
           INSERT PARAM[0] BLANK CHARS AT CURSOR POSITION
           WITH THE CHARACTER ATTRIBUTES SET TO NORMAL
        */
        case ICH:  /* Vt200 and greater */
        if(bd.Terminal.TermOptions.TermType != CDK_VT100)
          {
          /*  INSERT AT LEAST 1 CHARACTER  */
          if (Param[0] == 0)
            Param[0] = 1;
          InsertCharacterEx (&ScreenImage[0][0],
                 &AttributeMap[0][0],
               NULL,
               (LPSCREENVARS)&ScreenVars,
               Param[0]);
          }
        break;

        /*
            DELETE PARAM[0] CHARACTERS STARTING AT THE CURSOR POSITION
        */
        case DCH:
        /*  DELETE AT LEAST 1 CHARACTER  */
        if (Param[0] == 0)
          Param[0] = 1;
        DeleteCharacterEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
             NULL,
             (LPSCREENVARS)&ScreenVars,
             Param[0]);
        break;

        /*
           INSERT PARAM[0] LINES
        */
        case IL:
        /*  INSERT AT LEAST 1 LINE  */
        if (Param[0] == 0)
            Param[0] = 1;

        InsertLineEx (&ScreenImage[0][0],
                     &AttributeMap[0][0],
            NULL,
            (LPSCREENVARS)&ScreenVars,
            Param[0]);
        SetCursorPosition ((LPSCREENVARS)&ScreenVars,
                     (LPVTFLAGS)&VTFlags,
                   ScreenVars.CurrentRow,
                   0,
                   2);
        break;

        /*
            DELETE PARAM[0] LINES STARTING AT THE LINE WITH CURSOR
        */
    case DL:
        /*  DELETE AT LEAST 1 LINE  */
        if (Param[0] == 0)
            Param[0] = 1;

        DeleteLineEx (&ScreenImage[0][0],
                  &AttributeMap[0][0],
            NULL,
            (LPSCREENVARS)&ScreenVars,
            Param[0]);
        SetCursorPosition ((LPSCREENVARS)&ScreenVars,
                     (LPVTFLAGS)&VTFlags,
                   ScreenVars.CurrentRow,
                   0,
                   2);
            break;

    case 0x5c: /* DECUDK   VT220 ONLY */
        SetupFunctionKeys (Param2);
        break;

        /* CURSOR MOVEMENT */
        case CUB:       /* LEFT */
        if (ScreenVars.CurrentCol)
         {
            if (Param[0] == 0)
          Param[0] = 1;
        if ((ScreenVars.CurrentCol - Param[0]) >= 0)
                  ScreenVars.CurrentCol = ScreenVars.CurrentCol - Param[0];
        else
            ScreenVars.CurrentCol = 0;
         }
            break;

        case CUF:       /* RIGHT */
        if (ScreenVars.CurrentCol < ScreenVars.EndCol)
         {
            if (Param[0] == 0)
          Param[0] = 1;
        if ((ScreenVars.CurrentCol + Param[0]) <= ScreenVars.EndCol)
                  ScreenVars.CurrentCol = ScreenVars.CurrentCol + Param[0];
        else
            ScreenVars.CurrentCol = ScreenVars.EndCol;
         }
            break;

        case CUU:       /* UP */
        if(!bSLWrite)
          {
          AddToScrollScreen(ScreenVars.CurrentRow);    /* put the line in the scrolling screen region */
          if (fCaptureLine)
            CaptureLine ();
            AddLineAutoPrint(LF);    /* put this line in the file */
        /****  MID 11.07.1989 2.00.02  */
          if (ScreenVars.CurrentRow > ScreenVars.ScrollTop)
           {
              if (Param[0] == 0)
              Param[0] = 1;
              ScreenVars.CurrentRow = ScreenVars.CurrentRow - Param[0];

            if (ScreenVars.CurrentRow < ScreenVars.ScrollTop)
            ScreenVars.CurrentRow = ScreenVars.ScrollTop;
           }
          }
             break;

        case CUD:       /* DOWN */
        if(!bSLWrite)
         {
          AddToScrollScreen(ScreenVars.CurrentRow);    /* put the line in the scrolling screen region */
          if (fCaptureLine)
            CaptureLine ();
            AddLineAutoPrint(LF);    /* put this line in the file */
        /****  MID 11.07.1989 2.00.02  */
          if (ScreenVars.CurrentRow < ScreenVars.ScrollBottom)
           {
                if (Param[0] == 0)
              Param[0] = 1;
                ScreenVars.CurrentRow = ScreenVars.CurrentRow + Param[0];

            if (ScreenVars.CurrentRow > ScreenVars.ScrollBottom)
            ScreenVars.CurrentRow = ScreenVars.ScrollBottom;
           }
          }
            break;
        case CUP:       /* CURSOR POSITION (HOME) */
        case HVP:       /* HORIZONTAL & VERTICAL POSITION */
        /* RH Vb 2.00.01 Save the current value */
        lines = ScreenVars.EndRow;    /* save the current end row in a convenient store */
        if (fCaptureLine)
            CaptureLine ();

            AddLineAutoPrint(LF);    /* put this line in the file */
        AddToScrollScreen(ScreenVars.CurrentRow);    /* put the line in the scrolling screen region */
        if (Param[0] > 0)
            --Param[0];
        if (Param[1] > 0)
            --Param[1];

        /* if a VT320 term and in host write mode with the SL accessed then only the columns are affected */
        if((bd.Terminal.TermOptions.TermType == CDK_VT320)&& bSLWrite)
        ScreenVars.EndRow = Param[0] = LASTLINE;

        SetCursorPosition ((LPSCREENVARS)&ScreenVars,
                  (LPVTFLAGS)&VTFlags,
                Param[0],
                Param[1],
                2);
        faNewLine = FALSE;


        /* RH Vb 2.00.01 added the ifdef */
        ScreenVars.EndRow = lines;    /* reset the bottom row */
        break;


    case 'i':
        switch (Param[0])
         {
          case 0:    /*  PRINT SCREEN  */
               ScreenPrint();
            break;

        case 5:    /*  ACTIVATE PRINTER CONTROLLER  Esc[5i */
            DoPrintControl();
            break;
         }
        break;

    case 'h':
        switch (Param[0])
         {
            case 20: /* CAUSES LINE FEED TO DO A CR.  RETURN - CR & LF  */
                fLFCR = TRUE;
            break;

        case 4:  /*  IRM  Insert mode  */ /*NEWBIT*/
                VTFlags.WriteMode = TRUE; 
            break;

        case 12: /*  SRM  Local echo off  */
            bd.Terminal.TermOptions.LocalEcho = FALSE;
            break;
        case 2:  /*  KAM  Lock keyboard  */
            fKeyLock = TRUE;
            break;
        }
        break;

    case 'l':  /* SWITCH ABOVE OFF */
        switch (Param[0])
         {
            case 20: /* LINE FEED TO JUST LF  */
                fLFCR = FALSE;
          break;

        case 4:  /*  IRM  Replace mode  */
                  VTFlags.WriteMode = FALSE; 
            break;

        case 12: /*  SRM  Local echo on  */
            bd.Terminal.TermOptions.LocalEcho = TRUE;
            break;

        case 2:  /*  KAM  Unlock keyboard  */
            fKeyLock = FALSE;
            break;

         }
        break;

        case ECH:  /* ERASE CHARACTER  VT220 ONLY */
        if (Param[0] == 0)
             Param[0] = 1;
     
        if (Param[0] <= (BYTE)(((ScreenVars.EndCol + 1) - ScreenVars.CurrentCol)))
          ClearEx (&ScreenImage[0][0],
                  &AttributeMap[0][0],
                  NULL,
                  hWndMain,
                      (LPSCREENVARS)&ScreenVars,
                  (LPFONTVARS)&FontVars,
                  ScreenVars.CurrentRow,
                  ScreenVars.CurrentCol,
                  ScreenVars.CurrentRow,
                  ScreenVars.CurrentCol + Param[0] - 1,
                  FALSE);
        else
         {
          Param[0] = Param[0] - ((ScreenVars.EndCol + 1) - ScreenVars.CurrentCol);
        lines = Param[0] / (ScreenVars.EndCol + 1);
        Param[0] = Param[0] - ((ScreenVars.EndCol + 1) * lines);
        ClearEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
               NULL,
               hWndMain,
                   (LPSCREENVARS)&ScreenVars,
               (LPFONTVARS)&FontVars,
               ScreenVars.CurrentRow,
               ScreenVars.CurrentCol,
               ScreenVars.CurrentRow + lines + 1,
               Param[0],
               FALSE);
         }
        break;

        case ED:   /* DISPLAY */
      if (Param[0] == 0)  /*  Erase from cursor to end of screen  */
     {
        ClearEx (&ScreenImage[0][0],
           &AttributeMap[0][0],
           NULL,
           hWndMain,
               (LPSCREENVARS)&ScreenVars,
           (LPFONTVARS)&FontVars,
           ScreenVars.CurrentRow,
           ScreenVars.CurrentCol,
           ScreenVars.EndRow,
           ScreenVars.EndCol,
           FALSE);
         DecDWLHoldOff = TRUE;  
     }
      else
      if (Param[0] == 1)  /* Erase from screen start to cursor  */
     {
        ClearEx (&ScreenImage[0][0],
           &AttributeMap[0][0],
           NULL,
           hWndMain,
               (LPSCREENVARS)&ScreenVars,
           (LPFONTVARS)&FontVars,
           0,
           0,
           ScreenVars.CurrentRow,
           ScreenVars.CurrentCol,
           FALSE);
      DWLReset(0,ScreenVars.CurrentRow);
     }
      else
      if (Param[0] == 2)  /*  Erase all of screen  */
       {
        ClearEx (&ScreenImage[0][0],
           &AttributeMap[0][0],
           NULL,
           hWndMain,
               (LPSCREENVARS)&ScreenVars,
           (LPFONTVARS)&FontVars,
           0,
           0,
           ScreenVars.EndRow,
           ScreenVars.EndCol,
           FALSE);
      DWLReset(0,ScreenVars.EndRow);
       }
      break;

        case EL: /* LINE */
        if (Param[0] == 0)  /*  Erase from cursor to EOL  */
          ClearEx (&ScreenImage[0][0],
                 &AttributeMap[0][0],
                 NULL,
                 hWndMain,
                     (LPSCREENVARS)&ScreenVars,
                 (LPFONTVARS)&FontVars,
                 ScreenVars.CurrentRow,
                 ScreenVars.CurrentCol,
                 ScreenVars.CurrentRow,
                 ScreenVars.EndCol,
                 FALSE);
        else
        if (Param[0] == 1)  /*  Erase from line start to cursor  */
          ClearEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
               NULL,
               hWndMain,
                   (LPSCREENVARS)&ScreenVars,
               (LPFONTVARS)&FontVars,
               ScreenVars.CurrentRow,
               0,
               ScreenVars.CurrentRow,
               ScreenVars.CurrentCol,
               FALSE);
        else
        if (Param[0] == 2)  /*  Erase whole line  */
          ClearEx (&ScreenImage[0][0],
             &AttributeMap[0][0],
             NULL,
             hWndMain,
                 (LPSCREENVARS)&ScreenVars,
             (LPFONTVARS)&FontVars,
             ScreenVars.CurrentRow,
             0,
             ScreenVars.CurrentRow,
             ScreenVars.EndCol,
             FALSE);
        break;
        case TBC:       /* TABULATION CLEAR */
        if (Param[0] == 0)
            /*  CLEAR TAB STOP AT CURSOR POSITION  */
            ClearTabStop ((LPSCREENVARS)&ScreenVars, ScreenVars.CurrentCol);
        else if (Param[0] == 3)
          /*  CLEAR ALL TAB STOPS  */
          ClearTabStop ((LPSCREENVARS)&ScreenVars, -1);
       
        break;

    case DA:
        if (Param[0] == 0)
         {
#ifdef TERM320
         if(tWatch)
           SendDataBlock(IdentifyString,16,FALSE);
#endif
        PutComm(hWndMain,(LPSTR)IdentifyString, 16,(LPBUTTONDATA)&bd,(LPCOMMSVARS)&CommsVars,(BOOL FAR *)&fWaitingConnection);
         }
        break;

   

    case DECSSDT:    /* if the status line is being talked to then switch it off */
        SLReset();
        SetSLMode();  /* switch the status line mode */
        break;

    case DECSASD:
        SwitchStatusLine();
        break;

    case SGR:       /* Select Graphic Rendition */
        Sgr();
      break;

    default:
      if((c < '@') || (c > 0x7e))
        State = SQU_ERROR;
        break;
   }
}






/************************************************************************
*
        VT100Esc - Check for VT100 normal escape sequences
*
*************************************************************************/

VOID    VT100Esc (c)
BYTE    c;
{
#ifdef TERM320
   extern BOOL tWatch;
#endif
   int i;


  State = NORMAL;

   switch (c)
   {
        case RIS:
        ResetTerminal();
        break;

        case '=':
        VTFlags.fAppKeypad = TRUE;
            break;

        case '>':
        VTFlags.fAppKeypad = FALSE;
            break;

        case DECID:    /* Device attributes (WHAT ARE YOU) */
#ifdef TERM320
      if(tWatch)
         SendDataBlock(IdentifyString,16,FALSE);
#endif
        PutComm(hWndMain,(LPSTR)IdentifyString, 16,(LPBUTTONDATA)&bd,(LPCOMMSVARS)&CommsVars,(BOOL FAR *)&fWaitingConnection);
         break;

        case IND:    /* CURSOR DOWN WITH SCROLL */
        if (ScreenVars.CurrentRow < ScreenVars.ScrollBottom)
            ++ScreenVars.CurrentRow;
        else
        if (ScreenVars.CurrentRow == ScreenVars.ScrollBottom)
        {
            //ScrollVEx (&ScreenImage[0][0],
          //     &AttributeMap[0][0],
          //     NULL,
          //     (LPSCREENVARS)&ScreenVars,
            //   hWndMain,
         //  ScreenVars.ScrollTop,
         //  ScreenVars.ScrollBottom,
         //  1,
            //   (BUTTONDATA FAR *)&bd,
        //   (LPFONTVARS)&FontVars);
            ScrollVEx (
                   hWndMain,
                 ScreenVars.ScrollTop,
                 ScreenVars.ScrollBottom,
                 1);

          DWLScroll(ScreenVars.ScrollTop,ScreenVars.ScrollBottom,1);
        }
            break;

        case RI:     /* CURSOR UP WITH SCROLL */
        if (ScreenVars.CurrentRow > ScreenVars.ScrollTop)
            --ScreenVars.CurrentRow;
        else
        if (ScreenVars.CurrentRow == ScreenVars.ScrollTop)
        {
        //ScrollVEx (&ScreenImage[0][0],
          //       &AttributeMap[0][0],
          //       NULL,
         //    (LPSCREENVARS)&ScreenVars,
         //    hWndMain,
         //    ScreenVars.ScrollTop,
         //    ScreenVars.ScrollBottom,
         //    -1,
            //      (BUTTONDATA FAR *)&bd,
        //      (LPFONTVARS)&FontVars);
          ScrollVEx (hWndMain,
                    ScreenVars.ScrollTop,
                    ScreenVars.ScrollBottom,
                    -1);

         DWLScroll(ScreenVars.ScrollTop,ScreenVars.ScrollBottom,-1);
         }
            break;

        case NEL:    /* NEXT LINE WITH SCROLL */
        if (ScreenVars.CurrentRow == ScreenVars.ScrollBottom)
        {
            //ScrollVEx (&ScreenImage[0][0],
          //       &AttributeMap[0][0],
          //       NULL,
         //    (LPSCREENVARS)&ScreenVars,
           //       hWndMain,
         //    ScreenVars.ScrollTop,
         //    ScreenVars.ScrollBottom,
         //    1,
            //      (BUTTONDATA FAR *)&bd,
        //      (LPFONTVARS)&FontVars);
          ScrollVEx(hWndMain,
                    ScreenVars.ScrollTop,
                   ScreenVars.ScrollBottom,
                   1);


          DWLScroll(ScreenVars.ScrollTop,ScreenVars.ScrollBottom,1);
       }
        else
            ++ScreenVars.CurrentRow;
        ScreenVars.CurrentCol = 0;
            break;

    case DECSC:
        DecSc();  /*NEWBIT*/
            break;

        case DECRC:
        if(!CurSaveDone)    /* if not save was done then we use the default settings */
          SaveCursor = DefaultCursor;

        CurSaveDone = FALSE;
        ScreenVars.CurrentCol = SaveCursor.Col;
        ScreenVars.CurrentRow = SaveCursor.Row;
        bd.Terminal.TermOptions.Autowrap = SaveCursor.Wrap;
        VTFlags.fOrigin = SaveCursor.Origin;
        VTFlags.SelectErasable = SaveCursor.SelectErase;
        CharacterSet0 = SaveCursor.Chars0;
        CharacterSet1 = SaveCursor.Chars1;
      if(SaveCursor.CurrentSet)
        CurrentSet = &CharacterSet1;
      else
        CurrentSet = &CharacterSet0;
        fBold = SaveCursor.Bold;
        fUnderscore = SaveCursor.Under;
        fBlink = SaveCursor.Blink;
        fReverse = SaveCursor.Reverse;
            break;

        case HTS:
        ScreenVars.TabStops[ScreenVars.CurrentCol] = 1;
      break;

    case 'N':
    case 'O':
        fOneNormal = TRUE;
        break;

    case 'Z':
#ifdef TERM320
      if(tWatch)
         SendDataBlock(IdentifyString,16,FALSE);
#endif
        PutComm(hWndMain,(LPSTR)IdentifyString, 16,(LPBUTTONDATA)&bd,(LPCOMMSVARS)&CommsVars,(BOOL FAR *)&fWaitingConnection);
        break;    
    case DECSWL:    /* reset to a single width line */
        DecDWL[ScreenVars.CurrentRow].LineUsed = FALSE;
      DecDWL[ScreenVars.CurrentRow].LineType = ZERO;
         ScreenVars.LineUpdate[ScreenVars.CurrentRow] = TRUE;
        break;

    case DECDHLTOP:
    case DECDHLBOT:
    case DECDWL:    /* set up for single height double width */
        if(!DecDWL[ScreenVars.CurrentRow].LineUsed)
          ClearEx (&ScreenImage[0][0],            /* clear the 2nd hlaf of the line */
                 &AttributeMap[0][0],
                 NULL,
                 hWndMain,
                   (LPSCREENVARS)&ScreenVars,
                 (LPFONTVARS)&FontVars,
                 ScreenVars.CurrentRow,
                 ScreenVars.EndCol/2,
                 ScreenVars.CurrentRow,
                 ScreenVars.EndCol,
                 FALSE);

         ScreenVars.LineUpdate[ScreenVars.CurrentRow] = FALSE;
      DecDWL[ScreenVars.CurrentRow].LineUsed = TRUE;
      DecDWL[ScreenVars.CurrentRow].LineType = c;  /* the type of line */
         break;
    default:
      if((c < '@') || (c > 0x7e))
          State = SQU_ERROR;
        break;
   }
}







/************************************************************************
*
        VT100Private - Check for VT100 private sequences
*
*************************************************************************/

VOID    VT100Private (c)

BYTE    c;

{
    extern     WORD fOldTermType;
    extern  BOOL ReverseScreen;
    int    line,col;
    BYTE  forecolor,
         backcolor;
    LPBYTE tAttri;
    WORD  temp;

#define DECSCL    0x70  /* 'p' Selects Terminal type */

#define VT100MODE  61   
#define VT200MODE  62  /* the two possible modes */

  State = NORMAL;

    switch (c)
     {
    case DECSCL:      /* 'p' Terminal type set up */
        if(Param[0] == VT100MODE)  /* 61 */
          {
        SelectTransmissionStyle('F');
          bd.Terminal.TermOptions.TermType = CDK_VT100;
          }
        else  /* this is 62 but assume any other numer gives us back a VT320 */
          { 
          bd.Terminal.TermOptions.TermType = CDK_VT320;
            if(Param[1] == (BYTE)1)
           SelectTransmissionStyle('F');
            else
           SelectTransmissionStyle('G');
          }
        break;
           
    case 'q': /* DECSCA SELECT CHARACTER ATTRIBUTES VT220 */
        if(bd.Terminal.TermOptions.TermType != CDK_VT100)
          {
          if((Param[0] == 0) || (Param[0] == 2))
              VTFlags.SelectErasable = FALSE;
          else /* if (Param[0] == 1) */
              VTFlags.SelectErasable = TRUE;
          }
        break;

        case ED: /* SELECTIVE DISPLAY ERASE VT220 */
        if (Param[0] == 0)  /*  Erase from cursor to end of screen  */
          ClearEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
               NULL,
               hWndMain,
                   (LPSCREENVARS)&ScreenVars,
               (LPFONTVARS)&FontVars,
               ScreenVars.CurrentRow,
               ScreenVars.CurrentCol,
               ScreenVars.EndRow,
               ScreenVars.EndCol,
               TRUE);
        else
        if (Param[0] == 1)  /* Erase from screen start to cursor  */
          ClearEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
               NULL,
               hWndMain,
                   (LPSCREENVARS)&ScreenVars,
               (LPFONTVARS)&FontVars,
               0,
               0,
               ScreenVars.CurrentRow,
               ScreenVars.CurrentCol - 1,
               TRUE);
        else
        if (Param[0] == 2)  /*  Erase all of screen  */
          ClearEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
               NULL,
               hWndMain,
                   (LPSCREENVARS)&ScreenVars,
               (LPFONTVARS)&FontVars,
               0,
               0,
               ScreenVars.EndRow,
               ScreenVars.EndCol,
               TRUE);
        break;

        case EL: /* SELECTIVE LINE ERASE VT220 */
        if (Param[0] == 0)  /*  Erase from cursor to EOL  */
          ClearEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
               NULL,
               hWndMain,
                   (LPSCREENVARS)&ScreenVars,
               (LPFONTVARS)&FontVars,
               ScreenVars.CurrentRow,
               ScreenVars.CurrentCol,
               ScreenVars.CurrentRow,
               ScreenVars.EndCol,
               TRUE);
        else
        if (Param[0] == 1)  /*  Erase from line start to cursor  */
          ClearEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
               NULL,
               hWndMain,
                   (LPSCREENVARS)&ScreenVars,
               (LPFONTVARS)&FontVars,
               ScreenVars.CurrentRow,
               0,
               ScreenVars.CurrentRow,
               ScreenVars.CurrentCol,
               TRUE);
        else
        if (Param[0] == 2)  /*  Erase whole line  */
          ClearEx (&ScreenImage[0][0],
               &AttributeMap[0][0],
               NULL,
               hWndMain,
                   (LPSCREENVARS)&ScreenVars,
               (LPFONTVARS)&FontVars,
               ScreenVars.CurrentRow,
               0,
               ScreenVars.CurrentRow,
               ScreenVars.EndCol,
               TRUE);
        break;

        case DECSTBM:
        NewScrollSet(TRUE);  /* SET Scrolling Region */
        break;

        case 'l':
        case 'h':
        case 'i':
            switch (Param[0])
             {
                case DECCKM:    /* APPLICATION / CURSOR MODES */
            DecCkm(c);
            break;
        case DECANM:      /* VT52 Mode */
            if (c == 'l')
              {
               fOldTermType = bd.Terminal.TermOptions.TermType;
            bd.Terminal.TermOptions.TermType = CDK_VT52;
              }
            break;
        case DECCOLM:     /* COLUMN */
            if (!bd.Terminal.TermOptions.Cursor)
                       HideCaret (NULL);
            if((bd.Terminal.TermOptions.TermType == CDK_VT320)&&(bd.Terminal.TermOptions.StatusLine == CDK_HOSTWRITE))
              {
               tEndRow = ScreenVars.EndRow;
              ScreenVars.EndRow = LASTLINE;
              }

            if (c == 'h')
             {
                ChangeColMode (&ScreenImage[0][0],
                          &AttributeMap[0][0],
                          NULL,
                     hWndMain,
                     (LPFONTVARS)&FontVars,
                     (LPSCREENVARS)&ScreenVars,
                     (LPVTFLAGS)&VTFlags,
                     LASTCOL,(LPBUTTONDATA)&bd);
            if (VTFlags.fMaximized)    /* if we're maximized then add the scroll bar */
                SetScrollBars (TRUE);

                ChangeVTFont(hWndMain,AutoFontSelection((LPFONTSIZE)&FontSize[0],     /*  MID  29/06/1989  */
                 hWndMain,
                 (LPSCREENVARS)&ScreenVars,
                 FontVars.FontsLoaded)); 

              InvalidateRect(hWndMain,NULL,TRUE);
               }
            else
            if (c == 'l')
             {
                ChangeColMode (&ScreenImage[0][0],
                          &AttributeMap[0][0],
                          NULL,
                     hWndMain,
                         (LPFONTVARS)&FontVars,
                     (LPSCREENVARS)&ScreenVars,
                     (LPVTFLAGS)&VTFlags,
                     ID_80COL,(LPBUTTONDATA)&bd);

            if (VTFlags.fMaximized)    /* if we're maximized then remove the scroll bar */
                SetScrollBars (FALSE);

                   ChangeVTFont(hWndMain,AutoFontSelection((LPFONTSIZE)&FontSize[0],     /*  MID  29/06/1989  */
                 hWndMain,
                 (LPSCREENVARS)&ScreenVars,
                 FontVars.FontsLoaded));

              InvalidateRect(hWndMain,NULL,TRUE);
             }

            if((bd.Terminal.TermOptions.TermType == CDK_VT320)&&(bd.Terminal.TermOptions.StatusLine == CDK_HOSTWRITE))
            ScreenVars.EndRow = tEndRow;

            if(!bd.Terminal.TermOptions.Cursor && (GetFocus() == hWndMain))
              {
              SetCaretPos (CaretXPos(), CaretYPos());
            ShowCaret(NULL);
              }
            /* set Param array before resetting the scroll region */
            Param[0] = 1;
            Param[1] = 24;  /* default vals */
            Pnum = 2;
            NewScrollSet(TRUE);  
                   break;
                case DECSCNM:   /* SCREEN REVERSE / NORMAL */
            if (c == 'i')
              StartAutoPrint(DO_TITLE);  /* Start the auto print mode */
            else
             { 
            if((!ReverseScreen && (c == 'h')) || (ReverseScreen && (c == 'l')))
              {
                     ReverseScreenEx((LPSTR)bd.Data,(LPSTR)AttributeMap,(LPSCREENVARS)&ScreenVars);

                     for (line = 0; line < LASTLINE; line++)
                        if(!DecDWL[line].LineUsed)
                       ScreenVars.LineUpdate[line] = TRUE;
                    
                if(c == 'h')
                  ReverseScreen = TRUE;     /* set up for soft terminal reset */
                else
                  ReverseScreen = FALSE;
            }
              }
                  break;

                case DECOM:     /* ORIGIN */
            DecOm(c);
                     break;

                 case DECAWM:    /* AUTOWRAP */
               DecAwm(c);
                     break;

                 case DECTCEM:  /*  Hide and show cursor  */
            DecTcem(c);
            break;

                 case AUTOPRNOFF:  /* Auto Print Off */
            if(c == 'i')
            EndAutoPrint(DO_TITLE);  /* End the auto print mode */
                     break;

        case DECPFF:  /*  MID  12/09/1988   FF after print screen  */
            if (c == 'h')
                VTFlags.fFormFeed = TRUE;
            else
            if (c == 'l')
                VTFlags.fFormFeed = FALSE;
            break;

        case DECPEX:  /*  MID  12/09/1988   Print region  */
            if (c == 'h')
                VTFlags.fPrintExtent = FALSE;
            else
            if (c == 'l')
                VTFlags.fPrintExtent = TRUE;
            break;

             }
      break;
    default:
      if((c < '@') || (c > 0x7e))
        State = SQU_ERROR;
      break;
     }
}

1 В затмении.