Ejemplo n.º 1
0
        /// <summary>
        /// 解析CSI类命令
        /// </summary>
        /// <param name="data"></param>
        bool ParseCSICommand(RingQueue <byte> data)
        {
            /**
             * 命令基本为字母结尾
             * h: 模式设定(SET)
             * l: 模式设定(RESET)
             * A: 光标上移指定行 CSI [num] A
             * B: 光标下移指定行 CSI [num] B
             * C: 光标左移指定列 CSI [num] C
             * D: 光标右移指定列 CSI [num] D
             * H: 指定光标位置 CSI [num|column] ; [num|row] H
             * f: 同H
             * g: 清除一个水平Tab停止位置 CSI [num] g
             *      null/0: 清除当前位置的水平Tab停止
             *      3:清除所有
             * m: 设置图形渲染模式 CSI [num] ; [num] ... m
             *      0/null: 关闭所有
             *      1: 粗体
             *      4: 下划线
             *      5: 闪烁
             *      7: 反转显示
             *      2 2: 一般
             *      2 4: 不显示下划线
             *      2 5: 不显示闪烁
             *      2 7: 不反转
             * L: 光标指定位置插入指定行 CSI [num] L
             * M: 从光标所在行开始删除指定行 CSI [num] M
             * @: 从光标当前位置插入指定个字符(仅VT200) CSI [num] @
             * P: 从光标位置开始删除指定个字符 CSI [num] P
             * K: 删除字符 CSI [num] K
             *      null/0: 删除光标所在行右侧的字符(包含光标字符)
             *      1: 删除光标所在行左侧的字符(包含光标字符)
             *      2: 删除整行
             *
             *      ? null/0: 删除光标所在行右侧的字符(包含光标字符|仅VT200)
             *      ? 1: 删除光标所在行左侧的字符(包含光标字符|仅VT200)
             *      ? 2: 删除整行(仅VT200)
             * J: 删除字符 CSI [num] J
             *      null/0: 删除光标到屏幕结束的字符(包含光标字符)
             *      1: 删除光标到屏幕开始的字符(包含光标字符)
             *      2: 清除屏幕
             * r: 设置上下的页边距 CSI [top] ; [bottom] r
             * i: 打印设定 CSI [num] i
             *      ? 5: 开启自动打印模式
             *      ? 4: 关闭自动打印模式
             *      5: 开启打印控制模式
             *      4: 关闭打印控制模式
             *      ? 1: 打印当前行
             *      null/0: 打印当前屏幕
             *
             */

            while (!Encoding.ASCII.GetBytes("hlABCDHgmLMPJK@rif").Contains(data.GetNextValue()) &&
                   data.Current != data.FOOT)
            {
                ;
            }

            if (!Encoding.ASCII.GetBytes("hlABCDHgmLMPJK@rif").Contains(data.Value))
            {
                return(false);
            }

            var cmdbytes = data.LTrim().Select(o => Convert.ToByte(o)).ToArray();
            var cmd      = Encoding.ASCII.GetString(cmdbytes, 2, cmdbytes.Length - 3);

            switch (cmdbytes.Last())
            {
            case 0x66:     //f
                if (cmdbytes.Length > 3)
                {
                    if (cmd == ";")
                    {
                        Screen.CursorSetPos(0, 0);
                    }
                    else
                    {
                        var wh = cmd.Split(';');
                        wh[0] = wh[0] == "" ? "1" : wh[0];
                        wh[1] = wh[1] == "" ? "1" : wh[1];
                        Screen.CursorSetPos(int.Parse(wh[0]) - 1, int.Parse(wh[1]) - 1);
                    }
                }
                break;

            case 0x48:     //H
                if (cmdbytes.Length > 3)
                {
                    if (cmd == ";")
                    {
                        Screen.CursorSetPos(0, 0);
                    }
                    else
                    {
                        var wh = cmd.Split(';');
                        Screen.CursorSetPos(int.Parse(wh[0]) - 1, int.Parse(wh[1]) - 1);
                    }
                }
                break;

            case 0x4A:     //J
                if (cmdbytes.Length == 3)
                {
                    Screen.ScreenClearAfterCursor();
                }
                else
                {
                    switch (cmd)
                    {
                    case "0":
                        Screen.ScreenClearAfterCursor();
                        break;

                    case "1":
                        Screen.ScreenClearBeforeCursor();
                        break;

                    case "2":
                        Screen.ScreenClear();
                        break;
                    }
                }
                break;

            case 0x4B:     //K
                if (cmdbytes.Length == 3)
                {
                    Screen.LineClearAfterCursor();
                }
                else
                {
                    switch (cmd)
                    {
                    case "0":
                        Screen.LineClearAfterCursor();
                        break;

                    case "1":
                        Screen.LineClearBeforeCursor();
                        break;

                    case "2":
                        Screen.LineClear();
                        break;
                    }
                }
                break;

            case 0x68:     //h
                Logger.Debug("模式设定(SET):" + cmd.Substring(1));
                break;

            case 0x6C:     //l
                Logger.Debug("模式设定(RESET):" + cmd.Substring(1));
                break;

            case 0x6D:     //m
                if (cmdbytes.Length == 3)
                {
                    Screen.IsBold      = false;
                    Screen.IsUnderline = false;
                    Screen.IsBlinking  = false;
                    Screen.IsReverse   = false;
                }
                else
                {
                    foreach (var v in cmd.Split(';'))
                    {
                        switch (v)
                        {
                        case "":
                        case "0":
                            Screen.IsBold      = false;
                            Screen.IsUnderline = false;
                            Screen.IsBlinking  = false;
                            Screen.IsReverse   = false;
                            break;

                        case "1":
                            Screen.IsBold = true;
                            break;

                        case "4":
                            Screen.IsUnderline = true;
                            break;

                        case "5":
                            Screen.IsBlinking = true;
                            break;

                        case "7":
                            Screen.IsReverse = true;
                            break;

                        case "22":
                            Screen.IsBold = false;
                            break;

                        case "24":
                            Screen.IsUnderline = false;
                            break;

                        case "25":
                            Screen.IsBlinking = false;
                            break;

                        case "27":
                            Screen.IsReverse = false;
                            break;
                        }
                    }
                }
                Logger.Debug("样式渲染:" + cmd);
                break;

            case 0x69:     // i
                if (cmdbytes.Length == 3)
                {
                    Logger.Debug("打印当前屏幕");
                }
                else
                {
                    switch (cmd)
                    {
                    case "5":
                        if (PrintFileName == "")
                        {
                            PrintFileName = Environment.CurrentDirectory + "\\print.txt";
                        }
                        OnBeginPrint(new PrintEventArgs(PrintFileName));
                        IsPrinting = true;
                        Output     = new System.IO.FileStream(PrintFileName, System.IO.FileMode.Create);
                        TickCount  = Environment.TickCount;
                        Logger.Warn(string.Format("开始输出打印数据({0})", PrintFileName));
                        break;

                    case "4":
                        Logger.Warn("输出打印数据完成");
                        IsPrinting = false;
                        Output.Flush();
                        Output.Close();
                        Output = null;
                        OnEndPrint(new PrintEventArgs(PrintFileName));
                        Logger.Info("共耗时: " + (Environment.TickCount - TickCount) / 1000.0F + " 秒");
                        break;
                    }
                }
                break;

            default:
                Logger.Error("无法识别CSI指令: " + Encoding.ASCII.GetString(cmdbytes));
                break;
            }

            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 处理VT220协议数据
        /// </summary>
        /// <param name="data"></param>
        void ParseVT220Command(RingQueue <byte> data)
        {
            while (data.Count > 0)
            {
                var b = data.GetFirstValue();
                if (b == ESC)
                {
                    if (data.Count < 2)
                    {
                        break;
                    }

                    /**
                     * 第二指令说明: ESC [opt]
                     *
                     * N: 转交SS2命令处理
                     * O: 转交SS3命令处理
                     * P: 转交DCS命令处理
                     * [: 转交CSI命令处理
                     * \: 转交ST命令处理
                     * D: 光标向下移动一行(同IND命令),若光标在底部则内容向上滚动
                     * M: 光标向上移动一行(同RI命令),若光标在顶部则内容向下滚动
                     * E: 光标移动到下一行首位(同NEL命令),若光标在底部则内容向上滚动
                     * 7: 保存光标状态(光标位置,图形渲染,字符偏移状态,自动换行,参考点,删除内容区域)
                     * 8: 重置光标状态
                     * H: 设置水平Tab光标停留位置(同HTS命令)
                     * #: 行属性
                     *      ESC # 3 上半部
                     *      ESC # 4 下半部
                     *      ESC # 5 单倍宽度
                     *      ESC # 6 双倍宽度
                     * c: 硬重置终端
                     * =: 键盘模式(应用模式)
                     * >:键盘模式(数字模式)
                     * (: G0字符集 ESC ( [final]
                     * ): G1字符集 ESC ) [final]
                     * *: G2字符集 ESC * [final]
                     * +: G3字符集 ESC + [final]
                     */
                    switch (data.GetNextValue())
                    {
                    case 0x5B:    // [ ==> CSI
                        if (!ParseCSICommand(data))
                        {
                            return;
                        }
                        break;

                        #region 编码集设定
                    case 0x28:    // (
                        //Console.WriteLine("G0 " + data.GetNextValue().ToString());
                        Logger.Debug("编码集设定: " + "G0 " + data.GetNextValue().ToString());
                        Screen.Charset0 = ParseCharsets(data.Value);
                        data.LTrim();
                        break;

                    case 0x29:    // )
                        Logger.Debug("编码集设定: " + "G1 " + data.GetNextValue().ToString());
                        //Console.WriteLine("G1 " + data.GetNextValue().ToString());
                        Screen.Charset1 = ParseCharsets(data.Value);
                        data.LTrim();
                        break;

                    case 0x2A:    // *
                        Logger.Debug("编码集设定: " + "G2 " + data.GetNextValue().ToString());
                        //Console.WriteLine("G2 " + data.GetNextValue().ToString());
                        Screen.Charset2 = ParseCharsets(data.Value);
                        data.LTrim();
                        break;

                    case 0x2B:    // +
                        Logger.Debug("编码集设定: " + "G3 " + data.GetNextValue().ToString());
                        //Console.WriteLine("G3 " + data.GetNextValue().ToString());
                        Screen.Charset3 = ParseCharsets(data.Value);
                        data.LTrim();
                        break;
                        #endregion

                    case 0x3E:    // > 键盘模式(数字键盘) 参考4.6.18
                        Logger.Debug("键盘模式:数字模式");
                        //Console.WriteLine("键盘模式:数字模式");
                        data.LTrim();
                        break;
                    }
                }
                else if (b == 0x0F) //LS0 将G0字符集映射到GL
                {
                    Logger.Debug("G0字符集映射到GL");
                    Screen.Charset = Screen.Charset0;
                    data.LTrim();
                }
                else if (b == 0x0E) //LS1 将G1字符集映射到GL
                {
                    Logger.Debug("G1字符集映射到GL");
                    Screen.Charset = Screen.Charset1;
                    data.LTrim();
                }
                else if (b == 0x07) //Beep
                {
                    Console.Beep(250, 100);
                    data.LTrim();
                }
                else if (b == 0x08) //退格
                {
                    var pos = Screen.CursorPos;
                    pos.X--;
                    Screen.CursorPos = pos;
                    Screen.WriteByte(0);
                    Screen.CursorPos = pos;
                    data.LTrim();
                }
                else
                {
                    data.LTrim();
                    if (b != 0)
                    {
                        if (IsPrinting)
                        {
                            //输出到文件
                            Output.WriteByte(b);
                        }
                        else
                        {
                            Screen.WriteByte(b);
                        }
                    }
                }
            }
        }