[vte] emulation: Implement DECRQSS



commit c38cfbf5b7dedfe8eeaa2c6abefd13ca840a636e
Author: Christian Persch <chpe src gnome org>
Date:   Tue Mar 27 19:40:13 2018 +0200

    emulation: Implement DECRQSS
    
    For now, only DECSCUSR and DECSTBM requests are supported.

 src/parser-glue.hh  |   32 +++++++++++++++++--
 src/parser-reply.hh |   62 +++++++++++++++++++++----------------
 src/vte.cc          |   21 +++++++++++-
 src/vteinternal.hh  |    5 +++
 src/vteseq.cc       |   86 +++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 174 insertions(+), 32 deletions(-)
---
diff --git a/src/parser-glue.hh b/src/parser-glue.hh
index 39caf8e..f6a15b9 100644
--- a/src/parser-glue.hh
+++ b/src/parser-glue.hh
@@ -505,6 +505,13 @@ public:
                 m_arg_str = str;
         }
 
+        enum class Introducer {
+                NONE,
+                DEFAULT,
+                C0,
+                C1
+        };
+
         enum class ST {
                 NONE,
                 DEFAULT,
@@ -515,8 +522,8 @@ public:
 
 
 private:
-        void append_introducer(string_type& s,
-                               bool c1 = true) const noexcept
+        void append_introducer_(string_type& s,
+                                bool c1 = true) const noexcept
         {
                 /* Introducer */
                 if (c1) {
@@ -547,6 +554,24 @@ private:
                 }
         }
 
+        void append_introducer(string_type& s,
+                               bool c1 = true,
+                               Introducer introducer = Introducer::DEFAULT) const noexcept
+        {
+                switch (introducer) {
+                case Introducer::NONE:
+                        break;
+                case Introducer::DEFAULT:
+                        append_introducer_(s, c1);
+                        break;
+                case Introducer::C0:
+                        append_introducer_(s, false);
+                        break;
+                case Introducer::C1:
+                        append_introducer_(s, true);
+                }
+        }
+
         void append_params(string_type& s) const noexcept
         {
                 /* Parameters */
@@ -643,9 +668,10 @@ public:
         void to_string(string_type& s,
                        bool c1 = false,
                        ssize_t max_arg_str_len = -1,
+                       Introducer introducer = Introducer::DEFAULT,
                        ST st = ST::DEFAULT) const noexcept
         {
-                append_introducer(s, c1);
+                append_introducer(s, c1, introducer);
                 append_params(s);
                 append_intermediates_and_final(s);
                 append_arg_string(s, c1, max_arg_str_len, st);
diff --git a/src/parser-reply.hh b/src/parser-reply.hh
index b5d58b8..476debc 100644
--- a/src/parser-reply.hh
+++ b/src/parser-reply.hh
@@ -17,38 +17,46 @@
 
 _VTE_REPLY(NONE, NONE, 0, NONE, NONE,) /* placeholder */
 
+
 _VTE_REPLY(APC,         APC, 0,   NONE, NONE,  ) /* application program command */
-_VTE_REPLY(CPR,         CSI, 'R', NONE, NONE,  ) /* cursor position report */
+_VTE_REPLY(DECEKBD,     APC, 0,   NONE, NONE,  ) /* extended keyboard report */
+
+_VTE_REPLY(XTERM_FOCUS_IN,                            CSI, 'I', NONE, NONE,  ) /* XTERM focus in report */
+_VTE_REPLY(URXVT_MOUSE_EXT_REPORT,                    CSI, 'M', NONE, NONE,  ) /* URXVT mouse mode report */
+_VTE_REPLY(XTERM_MOUSE_EXT_SGR_REPORT_BUTTON_PRESS,   CSI, 'M', LT,   NONE,  ) /* XTERM SGR mouse mode 
button press report */
+_VTE_REPLY(XTERM_FOCUS_OUT,                           CSI, 'O', NONE, NONE,  ) /* XTERM focus out report */
+_VTE_REPLY(DECXCPR,                                   CSI, 'R', NONE, NONE,  ) /* extended cursor position 
report */
+_VTE_REPLY(CPR,                                       CSI, 'R', NONE, NONE,  ) /* cursor position report */
+_VTE_REPLY(DECDA1R,                                   CSI, 'c', WHAT, NONE,  ) /* DA1 report */
+_VTE_REPLY(DECDA2R,                                   CSI, 'c', GT,   NONE,  ) /* DA2 report */
+_VTE_REPLY(XTERM_MOUSE_EXT_SGR_REPORT_BUTTON_RELEASE, CSI, 'm', LT,   NONE,  ) /* XTERM SGR mouse mode 
button release report */
+_VTE_REPLY(DSR,                                       CSI, 'n', NONE, NONE,  ) /* device status report */
+_VTE_REPLY(DECDSR,                                    CSI, 'n', WHAT, NONE,  ) /* device status report */
+_VTE_REPLY(DECSCUSR,                                  CSI, 'q', NONE, SPACE, ) /* set-cursor-style */
+_VTE_REPLY(DECSTBM,                                   CSI, 'r', NONE, NONE,  ) /* set-top-and-bottom-margins 
*/
+_VTE_REPLY(XTERM_WM,                                  CSI, 't', NONE, NONE,  ) /* XTERM WM report */
+_VTE_REPLY(DECRPDE,                                   CSI, 'w', NONE, DQUOTE,) /* report displayed extent */
+_VTE_REPLY(DECRPKT,                                   CSI, 'v', NONE, COMMA, ) /* report key type */
+_VTE_REPLY(DECREPTPARM,                               CSI, 'x', NONE, NONE,  ) /* report terminal parameters 
*/
+_VTE_REPLY(DECPKMFR,                                  CSI, 'y', NONE, PLUS,  ) /* program key free memory 
report */
+_VTE_REPLY(DECRPM_ECMA,                               CSI, 'y', NONE, CASH,  ) /* report ECMA mode */
+_VTE_REPLY(DECRPM_DEC,                                CSI, 'y', WHAT, CASH,  ) /* report private mode */
+_VTE_REPLY(DECMSR,                                    CSI, '{', NONE, MULT,  ) /* macro space report */
+_VTE_REPLY(XTERM_BRACKET,                             CSI, '~', NONE, NONE,  ) /* XTERM bracketed paste */
+
+_VTE_REPLY(DECTABSR,    DCS, '@', NONE, CASH,  ) /* tabulation stop report */
+_VTE_REPLY(DECRPSS,     DCS, 'r', NONE, CASH,  ) /* report state or setting */
+_VTE_REPLY(DECTSR,      DCS, 's', NONE, CASH,  _VTE_REPLY_PARAMS({1})) /* terminal state report */
+_VTE_REPLY(DECCTR,      DCS, 's', NONE, CASH,  _VTE_REPLY_PARAMS({2})) /* color table report */
 _VTE_REPLY(DECAUPSS,    DCS, 'u', NONE, BANG,  ) /* assign user preferred supplemental set */
-_VTE_REPLY(DECDA1R,     CSI, 'c', WHAT, NONE,  ) /* DA1 report */
-_VTE_REPLY(DECDA2R,     CSI, 'c', GT,   NONE,  ) /* DA2 report */
 _VTE_REPLY(DECCIR,      DCS, 'u', NONE, CASH,  _VTE_REPLY_PARAMS({1})) /* cursor information report */
-_VTE_REPLY(DECCTR,      DCS, 's', NONE, CASH,  _VTE_REPLY_PARAMS({2})) /* color table report */
+_VTE_REPLY(DECRPTUI,    DCS, '|', NONE, BANG,  _VTE_REPLY_STRING("7E565445") /* "~VTE" */) /* report 
terminal unit ID */
+_VTE_REPLY(DECRPFK,     DCS, '}', NONE, DQUOTE,) /* report function key */
 _VTE_REPLY(DECCKSR,     DCS, '~', NONE, BANG,  ) /* memory checksum report */
-_VTE_REPLY(DECEKBD,     APC, 0,   NONE, NONE,  ) /* extended keyboard report */
-_VTE_REPLY(DECDSR,      CSI, 'n', WHAT, NONE,  ) /* device status report */
-_VTE_REPLY(DECMSR,      CSI, '{', NONE, MULT,  ) /* macro space report */
-_VTE_REPLY(DECPKMFR,    CSI, 'y', NONE, PLUS,  ) /* program key free memory report */
-_VTE_REPLY(DECREPTPARM, CSI, 'x', NONE, NONE,  ) /* report terminal parameters */
 _VTE_REPLY(DECRPAK,     DCS, '~', NONE, DQUOTE,) /* report all modifiers/alphanumeric key */
-_VTE_REPLY(DECRPDE,     CSI, 'w', NONE, DQUOTE,) /* report displayed extent */
-_VTE_REPLY(DECRPFK,     DCS, '}', NONE, DQUOTE,) /* report function key */
-_VTE_REPLY(DECRPKT,     CSI, 'v', NONE, COMMA, ) /* report key type */
-_VTE_REPLY(DECRPM_ECMA, CSI, 'y', NONE, CASH,  ) /* report ECMA mode */
-_VTE_REPLY(DECRPM_DEC,  CSI, 'y', WHAT, CASH,  ) /* report private mode */
-_VTE_REPLY(DECRPSS,     DCS, 'r', NONE, CASH,  ) /* report state or setting */
-_VTE_REPLY(DECRPTUI,    DCS, '|', NONE, BANG,  _VTE_REPLY_STRING("7E565445") /* "~VTE" */) /* report 
terminal unit ID */
-_VTE_REPLY(DECTABSR,    DCS, '@', NONE, CASH,  ) /* tabulation stop report */
-_VTE_REPLY(DECTSR,      DCS, 's', NONE, CASH,  _VTE_REPLY_PARAMS({1})) /* terminal state report */
-_VTE_REPLY(DECXCPR,     CSI, 'R', NONE, NONE,  ) /* extended cursor position report */
-_VTE_REPLY(DSR,         CSI, 'n', NONE, NONE,  ) /* device status report */
+
 _VTE_REPLY(OSC,         OSC, 0,   NONE, NONE,  ) /* operating system command */
+
 _VTE_REPLY(PM,          PM,  0,   NONE, NONE,  ) /* privacy message */
+
 _VTE_REPLY(SOS,         SOS, 0,   NONE, NONE,  ) /* start of string */
-_VTE_REPLY(URXVT_MOUSE_EXT_REPORT,                    CSI, 'M', NONE, NONE,) /* URXVT mouse mode report */
-_VTE_REPLY(XTERM_BRACKET,                             CSI, '~', NONE, NONE,) /* XTERM bracketed paste */
-_VTE_REPLY(XTERM_FOCUS_IN,                            CSI, 'I', NONE, NONE,) /* XTERM focus in report */
-_VTE_REPLY(XTERM_FOCUS_OUT,                           CSI, 'O', NONE, NONE,) /* XTERM focus out report */
-_VTE_REPLY(XTERM_MOUSE_EXT_SGR_REPORT_BUTTON_PRESS,   CSI, 'M', LT,   NONE,) /* XTERM SGR mouse mode button 
press report */
-_VTE_REPLY(XTERM_MOUSE_EXT_SGR_REPORT_BUTTON_RELEASE, CSI, 'm', LT,   NONE,) /* XTERM SGR mouse mode button 
release report */
-_VTE_REPLY(XTERM_WM,                                  CSI, 't', NONE, NONE,) /* XTERM WM report */
diff --git a/src/vte.cc b/src/vte.cc
index 9195183..421a8ea 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -3552,7 +3552,7 @@ skip_chunk:
        bbox_bottomright.x = bbox_bottomright.y = -G_MAXINT;
        bbox_topleft.x = bbox_topleft.y = G_MAXINT;
 
-        vte::parser::Sequence seq(m_parser);
+        vte::parser::Sequence seq{m_parser};
 
         m_line_wrapped = false;
 
@@ -4224,10 +4224,11 @@ VteTerminalPrivate::feed_child_using_modes(char const* data,
 void
 VteTerminalPrivate::send(vte::parser::u8SequenceBuilder const& builder,
                          bool c1,
+                         vte::parser::u8SequenceBuilder::Introducer introducer,
                          vte::parser::u8SequenceBuilder::ST st) noexcept
 {
         std::string str;
-        builder.to_string(str, c1, -1, st);
+        builder.to_string(str, c1, -1, introducer, st);
         feed_child(str.data(), str.size());
 }
 
@@ -4259,6 +4260,22 @@ void
 VteTerminalPrivate::reply(vte::parser::Sequence const& seq,
                           unsigned int type,
                           std::initializer_list<int> params,
+                          vte::parser::ReplyBuilder const& builder) noexcept
+{
+        std::string str;
+        builder.to_string(str, true, -1,
+                          vte::parser::ReplyBuilder::Introducer::NONE,
+                          vte::parser::ReplyBuilder::ST::NONE);
+
+        vte::parser::ReplyBuilder reply_builder{type, params};
+        reply_builder.set_string(std::move(str));
+        send(seq, reply_builder);
+}
+
+void
+VteTerminalPrivate::reply(vte::parser::Sequence const& seq,
+                          unsigned int type,
+                          std::initializer_list<int> params,
                           char const* format,
                           ...) noexcept
 {
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 1c44023..4b0f77f 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -1229,6 +1229,7 @@ public:
 
         void send(vte::parser::u8SequenceBuilder const& builder,
                   bool c1 = true,
+                  vte::parser::u8SequenceBuilder::Introducer introducer = 
vte::parser::u8SequenceBuilder::Introducer::DEFAULT,
                   vte::parser::u8SequenceBuilder::ST st = vte::parser::u8SequenceBuilder::ST::DEFAULT) 
noexcept;
         void send(vte::parser::Sequence const& seq,
                   vte::parser::u8SequenceBuilder const& builder) noexcept;
@@ -1240,6 +1241,10 @@ public:
         void reply(vte::parser::Sequence const& seq,
                    unsigned int type,
                    std::initializer_list<int> params,
+                   vte::parser::ReplyBuilder const& builder) noexcept;
+        void reply(vte::parser::Sequence const& seq,
+                   unsigned int type,
+                   std::initializer_list<int> params,
                    char const* format,
                    ...) noexcept G_GNUC_PRINTF(5, 6);
 
diff --git a/src/vteseq.cc b/src/vteseq.cc
index e361583..ba30243 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -2994,9 +2994,95 @@ VteTerminalPrivate::DECRQSS(vte::parser::Sequence const& seq)
 {
         /*
          * DECRQSS - request selection or setting
+         * The DATA string contains the intermediate(s) and final
+         * character of a CSI sequence that codes for which
+         * selection or setting to report.
+         *
+         * Reply: DECRPSS
+         *   @args[0]: 0 if the request was valid, otherwise 1
+         *   DATA: the current value of the selection or setting
+         *
+         * Note that xterm is buggy; it sends 1 for a valid and
+         *   0 for an invalid request; we follow the VT525
+         *   behaviour instead of xterm.
          *
          * References: VT525
          */
+
+        /* Use a subparser to get the command from the request */
+        vte::parser::Parser parser{};
+        parser.feed(0x9b); /* CSI */
+
+        int rv = VTE_SEQ_NONE;
+
+        /* If at the end, the parser returns a VTE_SEQ_CSI sequence,
+         * we interpret that; otherwise we ignore the request and
+         * send only a dummy reply.
+         */
+        auto const str = seq.string();
+        for (size_t i = 0; i < str.size(); ++i) {
+                auto const c = str[i];
+                if (c < 0x20 || c >= 0x7f)
+                        break;
+                rv = parser.feed(c);
+        }
+
+        vte::parser::Sequence request{parser};
+        if (rv != VTE_SEQ_CSI || request.size() > 0 /* any parameters */)
+                return reply(seq, VTE_REPLY_DECRPSS, {1});
+
+        switch (request.command()) {
+
+        case VTE_CMD_DECSCUSR:
+                return reply(seq, VTE_REPLY_DECRPSS, {0}, {VTE_REPLY_DECSCUSR, {m_cursor_style}});
+
+        case VTE_CMD_DECSTBM:
+                if (m_scrolling_restricted)
+                        return reply(seq, VTE_REPLY_DECRPSS, {0},
+                                     {VTE_REPLY_DECSTBM,
+                                                     {m_scrolling_region.start + 1,
+                                                                     m_scrolling_region.end + 1}});
+                else
+                        return reply(seq, VTE_REPLY_DECRPSS, {0}, {VTE_REPLY_DECSTBM, {}});
+
+        /* case VTE_CMD_DECAC: */
+        /* case VTE_CMD_DECARR: */
+        /* case VTE_CMD_DECATC: */
+        /* case VTE_CMD_DECCRTST: */
+        /* case VTE_CMD_DECDLDA: */
+        case VTE_CMD_DECSACE:
+        case VTE_CMD_DECSASD:
+        case VTE_CMD_DECSCA:
+        case VTE_CMD_DECSCL:
+        case VTE_CMD_DECSCP:
+        case VTE_CMD_DECSCPP:
+        case VTE_CMD_DECSCS:
+        case VTE_CMD_DECSDDT:
+        case VTE_CMD_DECSDPT:
+        /* case VTE_CMD_DECSEST: */
+        case VTE_CMD_DECSFC:
+        case VTE_CMD_DECSKCV:
+        case VTE_CMD_DECSLCK:
+        case VTE_CMD_DECSLPP:
+        /* case VTE_CMD_DECSLRM: */
+        case VTE_CMD_DECSMBV:
+        case VTE_CMD_DECSNLS:
+        /* case VTE_CMD_DECSPMA: */
+        case VTE_CMD_DECSPP:
+        case VTE_CMD_DECSPPCS:
+        case VTE_CMD_DECSPRTT:
+        case VTE_CMD_DECSSCLS:
+        case VTE_CMD_DECSSDT:
+        case VTE_CMD_DECSSL:
+        /* case VTE_CMD_DECSTGLT: */
+        case VTE_CMD_DECSTRL:
+        case VTE_CMD_DECSWBV:
+        /* case VTE_CMD_DECSZS: */
+        case VTE_CMD_DECTME:
+        case VTE_CMD_SGR:
+        default:
+                return reply(seq, VTE_REPLY_DECRPSS, {1});
+        }
 }
 
 void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]