Пример #1
0
        private static void AnsiCommand(char ACommand)
        {
            lock (_Lock)
            {
                int Colour = 0;
                int X      = 0;
                int Y      = 0;
                int Z      = 0;

                switch (ACommand)
                {
                case 'A':     // CSI n A - Moves the cursor n (default 1) cells up. If the cursor is already at the edge of the screen, this has no effect.
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    Y = Math.Max(1, Crt.WhereY() - Y);
                    Crt.GotoXY(Crt.WhereX(), Y);
                    break;

                case 'B':     // CSI n B - Moves the cursor n (default 1) cells down. If the cursor is already at the edge of the screen, this has no effect.
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    Y = Math.Min(Crt.WindRows, Crt.WhereY() + Y);
                    Crt.GotoXY(Crt.WhereX(), Y);
                    break;

                case 'C':     // CSI n C - Moves the cursor n (default 1) cells right. If the cursor is already at the edge of the screen, this has no effect.
                    X = Math.Max(1, _AnsiParams.Dequeue());
                    X = Math.Min(Crt.WindCols, Crt.WhereX() + X);
                    Crt.GotoXY(X, Crt.WhereY());
                    break;

                case 'D':     // CSI n D - Moves the cursor n (default 1) cells left. If the cursor is already at the edge of the screen, this has no effect.
                    X = Math.Max(1, _AnsiParams.Dequeue());
                    X = Math.Max(1, Crt.WhereX() - X);
                    Crt.GotoXY(X, Crt.WhereY());
                    break;

                case 'E':     // CSI n E - Moves cursor to beginning of the line n (default 1) lines down.
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    Y = Math.Min(Crt.WindRows, Crt.WhereY() + Y);
                    Crt.GotoXY(1, Y);
                    break;

                case 'F':     // CSI n F - Moves cursor to beginning of the line n (default 1) lines up.
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    Y = Math.Max(1, Crt.WhereY() - Y);
                    Crt.GotoXY(1, Y);
                    break;

                case 'f':             // CSI y ; x f or CSI ; x f or CSI y ; f - Moves the cursor to row y, column x. The values are 1-based, and default to 1 (top left corner) if omitted. A sequence such as CSI ;5f is a synonym for CSI 1;5f as well as CSI 17;f is the same as CSI 17f and CSI 17;1f
                    AnsiCommand('H'); // Cheat and just call the more common H equivalent
                    break;

                case 'G':     // CSI n G - Moves the cursor to column n.
                    X = Math.Max(1, _AnsiParams.Dequeue());
                    if ((X >= 1) && (X <= Crt.WindCols))
                    {
                        Crt.GotoXY(X, Crt.WhereY());
                    }
                    break;

                case 'H':     // CSI y ; x H or CSI ; x H or CSI y ; H - Moves the cursor to row y, column x. The values are 1-based, and default to 1 (top left corner) if omitted. A sequence such as CSI ;5H is a synonym for CSI 1;5H as well as CSI 17;H is the same as CSI 17H and CSI 17;1H
                    while (_AnsiParams.Count < 2)
                    {
                        _AnsiParams.Enqueue(1);                               // Make sure we have enough parameters
                    }
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    X = Math.Max(1, _AnsiParams.Dequeue());
                    Crt.GotoXY(X, Y);
                    break;

                case 'h':     // CSI n h
                    // n = 7 enables auto line wrap when writing to last column of screen (which is on by default so we ignore the sequence)
                    X = _AnsiParams.Dequeue();
                    switch (X)
                    {
                    case 7: /* Ignore */ break;

                    case 25: Crt.ShowCursor(); break;
                    }
                    break;

                case 'J':     // CSI n J - Clears part of the screen. If n is zero (or missing), clear from cursor to end of screen. If n is one, clear from cursor to beginning of the screen. If n is two, clear entire screen (and moves cursor to upper left on MS-DOS ANSI.SYS).
                    switch (_AnsiParams.Dequeue())
                    {
                    case 0: Crt.ClrEos(); break;

                    case 1: Crt.ClrBos(); break;

                    case 2: Crt.ClrScr(); break;
                    }
                    break;

                case 'K':     // CSI n K - Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
                    switch (_AnsiParams.Dequeue())
                    {
                    case 0: Crt.ClrEol(); break;

                    case 1: Crt.ClrBol(); break;

                    case 2: Crt.ClrLine(); break;
                    }
                    break;

                case 'L':     // CSI n L - Insert n new lines, pushing the current line and those below it down
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    Crt.InsLine(Y);
                    break;

                case 'l':     // CSI n l
                    // n = 7 disables auto line wrap when writing to last column of screen (we dont support this)
                    X = _AnsiParams.Dequeue();
                    switch (X)
                    {
                    case 7: /* Ignore */ break;

                    case 25: Crt.HideCursor(); break;
                    }
                    break;

                case 'M':     // CSI n M - Delete n lines, pulling the lines below the deleted lines up
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    Crt.DelLine(Y);
                    break;

                case 'm':     // CSI n [;k] m - Sets SGR parameters. After CSI can be zero or more parameters separated with ;. With no parameters, CSI m is treated as CSI 0 m (reset / normal), which is typical of most of the ANSI escape sequences.
                    while (_AnsiParams.Count > 0)
                    {
                        X = _AnsiParams.Dequeue();
                        switch (X)
                        {
                        case 0:         // Reset / Normal (all attributes off)
                            Crt.NormVideo();
                            break;

                        case 1:         // Intensity: Bold
                            Crt.HighVideo();
                            break;

                        case 2:         // Intensity: Faint (not widely supported)
                            break;

                        case 3:         // Italic: on (not widely supported)
                            break;

                        case 4:         // Underline: Single
                            break;

                        case 5:         // Blink: Slow (< 150 per minute)
                            Crt.TextAttr |= Crt.Blink;
                            Crt.SetBlinkRate(500);
                            break;

                        case 6:         // Blink: Rapid (>= 150 per minute)
                            Crt.TextAttr |= Crt.Blink;
                            Crt.SetBlinkRate(250);
                            break;

                        case 7:         // Image: Negative (swap foreground and background)
                            Crt.ReverseVideo();
                            break;

                        case 8:         // Conceal (not widely supported)
                            _AnsiAttr = Crt.TextAttr;
                            Crt.Conceal();
                            break;

                        case 21:         // Underline: Double (not widely supported)
                            break;

                        case 22:         //	Intensity: Normal (not widely supported)
                            Crt.LowVideo();
                            break;

                        case 24:         // Underline: None
                            break;

                        case 25:         // Blink: off
                            Crt.TextAttr &= ~Crt.Blink;
                            break;

                        case 27:         // Image: Positive (handle the same as negative
                            Crt.ReverseVideo();
                            break;

                        case 28:         // Reveal (conceal off)
                            Crt.TextAttr = _AnsiAttr;
                            break;

                        case 30:         // Set foreground color, normal intensity
                        case 31:
                        case 32:
                        case 33:
                        case 34:
                        case 35:
                        case 36:
                        case 37:
                            Colour = ANSI_COLORS[X - 30];
                            if (Crt.TextAttr % 16 > 7)
                            {
                                Colour += 8;
                            }
                            Crt.TextColor(Colour);
                            break;

                        case 40:         // Set background color, normal intensity
                        case 41:
                        case 42:
                        case 43:
                        case 44:
                        case 45:
                        case 46:
                        case 47:
                            Colour = ANSI_COLORS[X - 40];
                            Crt.TextBackground(Colour);
                            break;
                        }
                    }
                    break;

                case 'n':     // CSI X n
                    //       n = 5 Device status report (reply with \x1B[0n to report "ready, no malfunction detected")
                    //       n = 6 Reports the cursor position to the application as (as though typed at the keyboard) ESC[n;mR, where n is the row and m is the column. (May not work on MS-DOS.)
                    //       n = 255 Reports the bottom right cursor position (essentially the screen size)
                    X = _AnsiParams.Dequeue();
                    switch (X)
                    {
                    case 5: RaiseESC5nEvent(); break;

                    case 6: RaiseESC6nEvent(); break;

                    case 255: RaiseESC255nEvent(); break;
                    }
                    break;

                case 'Q':     // CSI cp ; x ; y Q - NON-STANDARD fTelnet EXTENSION - Changes the current font to CodePage=cp, Width=x, Height=y
                    while (_AnsiParams.Count < 3)
                    {
                        _AnsiParams.Enqueue(0);                               // Make sure we have enough parameters
                    }
                    X = _AnsiParams.Dequeue();
                    Y = _AnsiParams.Dequeue();
                    Z = _AnsiParams.Dequeue();
                    RaiseESCQEvent(X, Y, Z);
                    break;

                case 'S':     // CSI n S - Scroll whole page up by n (default 1) lines. New lines are added at the bottom. (not ANSI.SYS)
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    Crt.ScrollUpScreen(Y);
                    break;

                case 's':     // CSI s - Saves the cursor position.
                    _SavedX = Crt.WhereX();
                    _SavedY = Crt.WhereY();
                    break;

                case 'T':     // CSI n T - Scroll whole page down by n (default 1) lines. New lines are added at the top. (not ANSI.SYS)
                    Y = Math.Max(1, _AnsiParams.Dequeue());
                    Crt.ScrollDownWindow(Y);
                    break;

                case 'u':     // CSI u - Restores the cursor position.
                    if ((_SavedX > 0) && (_SavedY > 0))
                    {
                        Crt.GotoXY(_SavedX, _SavedY);
                    }
                    break;
                }
            }
        }