[vte] parser: Improve glue for subparameters
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] parser: Improve glue for subparameters
- Date: Tue, 27 Mar 2018 17:42:07 +0000 (UTC)
commit edcb9d8ffaf3aa755df90637767c4dd04f949588
Author: Christian Persch <chpe src gnome org>
Date: Tue Mar 27 19:40:12 2018 +0200
parser: Improve glue for subparameters
... and use it to parse SGR with subparameters.
src/parser-arg.hh | 8 +-
src/parser-glue.hh | 178 +++++++++++++++++--
src/parser-test.cc | 84 ++++++++-
src/vteinternal.hh | 6 +-
src/vteseq-list.hh | 1 -
src/vteseq.cc | 520 ++++++++++++++++++----------------------------------
6 files changed, 426 insertions(+), 371 deletions(-)
---
diff --git a/src/parser-arg.hh b/src/parser-arg.hh
index 87d9343..ead82f0 100644
--- a/src/parser-arg.hh
+++ b/src/parser-arg.hh
@@ -152,10 +152,12 @@ static constexpr inline int vte_seq_arg_nonfinal(vte_seq_arg_t arg)
/*
* vte_seq_arg_value:
* @arg:
+ * @default_value: (defaults to -1)
*
- * Returns: the value of @arg, or -1 if @arg has default value
+ * Returns: the value of @arg, or @default_value if @arg has default value
*/
-static constexpr inline int vte_seq_arg_value(vte_seq_arg_t arg)
+static constexpr inline int vte_seq_arg_value(vte_seq_arg_t arg,
+ int default_value = -1)
{
- return (arg & VTE_SEQ_ARG_FLAG_VALUE) ? (arg & VTE_SEQ_ARG_VALUE_MASK) : -1;
+ return (arg & VTE_SEQ_ARG_FLAG_VALUE) ? (arg & VTE_SEQ_ARG_VALUE_MASK) : default_value;
}
diff --git a/src/parser-glue.hh b/src/parser-glue.hh
index c06bf19..5a48887 100644
--- a/src/parser-glue.hh
+++ b/src/parser-glue.hh
@@ -1,5 +1,5 @@
/*
- * Copyright © 2017 Christian Persch
+ * Copyright © 2017, 2018 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,6 +17,9 @@
#pragma once
+#include <cstdint>
+#include <algorithm>
+
#include "parser.hh"
namespace vte {
@@ -28,29 +31,180 @@ public:
typedef int number;
- char* ucs4_to_utf8(gunichar const* str) const;
+ char* ucs4_to_utf8(gunichar const* str) const noexcept;
- void print() const;
+ void print() const noexcept;
- inline unsigned int type() const { return m_seq->type; }
+ /* type:
+ *
+ *
+ * Returns: the type of the sequence, a value from the VTE_SEQ_* enum
+ */
+ inline constexpr unsigned int type() const noexcept
+ {
+ return m_seq->type;
+ }
- inline unsigned int command() const { return m_seq->command; }
+ /* command:
+ *
+ * Returns: the command the sequence codes for, a value
+ * from the VTE_CMD_* enum, or %VTE_CMD_NONE if the command is
+ * unknown
+ */
+ inline constexpr unsigned int command() const noexcept
+ {
+ return m_seq->command;
+ }
- inline unsigned int charset() const { return m_seq->charset; }
+ /* charset:
+ *
+ * This is the charset to use in a %VTE_CMD_GnDm, %VTE_CMD_GnDMm,
+ * %VTE_CMD_CnD or %VTE_CMD_DOCS command.
+ *
+ * Returns: the charset, a value from the VTE_CHARSET_* enum.
+ */
+ inline constexpr unsigned int charset() const noexcept
+ {
+ return m_seq->charset;
+ }
- inline unsigned int intermediates() const { return m_seq->intermediates; }
+ /* intermediates:
+ *
+ * The intermediate bytes of the ESCAPE, CSI or DCS sequence.
+ *
+ * Returns: the immediates as flag values from the VTE_SEQ_FLAG_* enum
+ */
+ inline constexpr unsigned int intermediates() const noexcept
+ {
+ return m_seq->intermediates;
+ }
- inline uint32_t terminator() const { return m_seq->terminator; }
+ /* terminator:
+ *
+ * This is the character terminating the sequence, or, for a
+ * %VTE_SEQ_GRAPHIC sequence, the graphic character.
+ *
+ * Returns: the terminating character
+ */
+ inline constexpr uint32_t terminator() const noexcept
+ {
+ return m_seq->terminator;
+ }
- inline unsigned int size() const
+ /* size:
+ *
+ * Returns: the number of parameters
+ */
+ inline constexpr unsigned int size() const noexcept
{
- g_assert_nonnull(m_seq);
return m_seq->n_args;
}
- inline int operator[](int position) const
+
+ /* size:
+ *
+ * Returns: the number of parameter blocks, counting runs of subparameters
+ * as only one parameter
+ */
+ inline constexpr unsigned int size_final() const noexcept
+ {
+ return m_seq->n_final_args;
+ }
+
+ /* capacity:
+ *
+ * Returns: the number of parameter blocks, counting runs of subparameters
+ * as only one parameter
+ */
+ inline constexpr unsigned int capacity() const noexcept
+ {
+ return G_N_ELEMENTS(m_seq->args);
+ }
+
+ /* param:
+ * @idx:
+ * @default_v: the value to use for default parameters
+ *
+ * Returns: the value of the parameter at index @idx, or @default_v if
+ * the parameter at this index has default value, or the index
+ * is out of bounds
+ */
+ inline constexpr int param(unsigned int idx,
+ int default_v = -1) const noexcept
+ {
+ return __builtin_expect(idx < size(), 1) ? vte_seq_arg_value(m_seq->args[idx], default_v) :
default_v;
+ }
+
+ /* param:
+ * @idx:
+ * @default_v: the value to use for default parameters
+ * @min_v: the minimum value
+ * @max_v: the maximum value
+ *
+ * Returns: the value of the parameter at index @idx, or @default_v if
+ * the parameter at this index has default value, or the index
+ * is out of bounds. The returned value is clamped to the
+ * range @min_v..@max_v.
+ */
+ inline constexpr int param(unsigned int idx,
+ int default_v,
+ int min_v,
+ int max_v) const noexcept
+ {
+ auto v = param(idx, default_v);
+ return std::min(std::max(v, min_v), max_v);
+ }
+
+ /* param_nonfinal:
+ * @idx:
+ *
+ * Returns: whether the parameter at @idx is nonfinal, i.e.
+ * there are more subparameters after it.
+ */
+ inline constexpr bool param_nonfinal(unsigned int idx) const noexcept
+ {
+ return __builtin_expect(idx < size(), 1) ? vte_seq_arg_nonfinal(m_seq->args[idx]) : false;
+ }
+
+ /* param_default:
+ * @idx:
+ *
+ * Returns: whether the parameter at @idx has default value
+ */
+ inline constexpr bool param_default(unsigned int idx) const noexcept
+ {
+ return __builtin_expect(idx < size(), 1) ? vte_seq_arg_default(m_seq->args[idx]) : true;
+ }
+
+ /* next:
+ * @idx:
+ *
+ * Returns: the index of the next parameter block
+ */
+ inline constexpr unsigned int next(unsigned int idx) const noexcept
+ {
+ /* Find the final parameter */
+ while (param_nonfinal(idx))
+ ++idx;
+ /* And return the index after that one */
+ return ++idx;
+ }
+
+ inline constexpr unsigned int cbegin() const noexcept
+ {
+ return 0;
+ }
+
+ inline constexpr unsigned int cend() const noexcept
+ {
+ return size();
+ }
+
+
+ //FIMXE remove this one
+ inline constexpr int operator[](int position) const
{
- return G_LIKELY(position < (int)size()) ? vte_seq_arg_value(m_seq->args[position]) : -1;
+ return __builtin_expect(position < (int)size(), 1) ?
vte_seq_arg_value(m_seq->args[position]) : -1;
}
inline bool has_number_at_unchecked(unsigned int position) const
diff --git a/src/parser-test.cc b/src/parser-test.cc
index 649fd4e..a207675 100644
--- a/src/parser-test.cc
+++ b/src/parser-test.cc
@@ -28,6 +28,7 @@
#include <glib.h>
#include "parser.hh"
+#include "parser-glue.hh"
#include "parser-charset-tables.hh"
static struct vte_parser* parser;
@@ -795,21 +796,29 @@ test_seq_csi(void)
}
static void
-test_seq_csi_param(char const* str,
- std::vector<int> args,
- std::vector<bool> args_nonfinal)
+test_seq_parse(char const* str,
+ struct vte_seq** seq)
{
- g_assert_cmpuint(args.size(), ==, args_nonfinal.size());
-
std::u32string s;
s.push_back(0x9B); /* CSI */
for (unsigned int i = 0; str[i]; i++)
s.push_back(str[i]);
s.push_back(0x6d); /* m = SGR */
- struct vte_seq* seq;
- auto rv = feed_parser(s, &seq);
+ vte_parser_reset(parser);
+ auto rv = feed_parser(s, seq);
g_assert_cmpint(rv, ==, VTE_SEQ_CSI);
+}
+
+static void
+test_seq_csi_param(char const* str,
+ std::vector<int> args,
+ std::vector<bool> args_nonfinal)
+{
+ g_assert_cmpuint(args.size(), ==, args_nonfinal.size());
+
+ struct vte_seq* seq;
+ test_seq_parse(str, &seq);
if (seq->n_args < VTE_PARSER_ARG_MAX)
g_assert_cmpuint(seq->n_args, ==, args.size());
@@ -855,6 +864,66 @@ test_seq_csi_param(void)
}
+static void
+test_seq_glue(char const* str,
+ unsigned int n_args,
+ unsigned int n_final_args,
+ vte::parser::Sequence& seq)
+{
+ test_seq_parse(str, seq.seq_ptr());
+
+ auto raw_seq = *seq.seq_ptr();
+ g_assert_cmpuint(seq.size(), ==, n_args);
+ g_assert_cmpuint(raw_seq->n_args, ==, n_args);
+ g_assert_cmpuint(seq.size_final(), ==, n_final_args);
+ g_assert_cmpuint(raw_seq->n_final_args, ==, n_final_args);
+
+ g_assert_cmpuint(seq.type(), ==, raw_seq->type);
+ g_assert_cmpuint(seq.command(), ==, raw_seq->command);
+ g_assert_cmpuint(seq.terminator(), ==, raw_seq->terminator);
+ g_assert_cmpuint(seq.intermediates(), ==, raw_seq->intermediates);
+
+ for (unsigned int i = 0; i < raw_seq->n_args; i++)
+ g_assert_cmpuint(seq.param(i), ==, vte_seq_arg_value(raw_seq->args[i]));
+}
+
+static void
+test_seq_glue(void)
+{
+ vte::parser::Sequence seq{};
+
+ test_seq_glue(":0:1000;2;:", 6, 3, seq);
+ g_assert_cmpuint(seq.cbegin(), ==, 0);
+ g_assert_cmpuint(seq.cend(), ==, 6);
+
+ auto it = seq.cbegin();
+ g_assert_cmpuint(it, ==, 0);
+ it = seq.next(it);
+ g_assert_cmpuint(it, ==, 3);
+ it = seq.next(it);
+ g_assert_cmpuint(it, ==, 4);
+ it = seq.next(it);
+ g_assert_cmpuint(it, ==, 6);
+
+ it = seq.cbegin();
+ g_assert_cmpint(seq.param(it++), ==, -1);
+ g_assert_cmpint(seq.param(it++), ==, 0);
+ g_assert_cmpint(seq.param(it++), ==, 1000);
+ g_assert_cmpint(seq.param(it++), ==, 2);
+ g_assert_cmpint(seq.param(it++), ==, -1);
+ g_assert_cmpint(seq.param(it++), ==, -1);
+ g_assert_cmpint(it, ==, seq.cend());
+
+ it = seq.cbegin();
+ g_assert_cmpint(seq.param(it, -2), ==, -2);
+ g_assert_cmpint(seq.param(it, -2, 0, 100), ==, 0);
+ it++; it++;
+ g_assert_cmpint(seq.param(it, -2), ==, seq.param(it));
+ g_assert_cmpint(seq.param(it, -2, 20, 100), ==, 100);
+ g_assert_cmpint(seq.param(it, -2, 200, 2000), ==, 1000);
+ g_assert_cmpint(seq.param(it, -2, 2000, 4000), ==, 2000);
+}
+
int
main(int argc,
char* argv[])
@@ -865,6 +934,7 @@ main(int argc,
return 1;
g_test_add_func("/vte/parser/sequences/arg", test_seq_arg);
+ g_test_add_func("/vte/parser/sequences/glue", test_seq_glue);
g_test_add_func("/vte/parser/sequences/control", test_seq_control);
g_test_add_func("/vte/parser/sequences/escape/invalid", test_seq_esc_invalid);
g_test_add_func("/vte/parser/sequences/escape/charset/94", test_seq_esc_charset_94);
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index d529376..d23f6c7 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -1213,9 +1213,9 @@ public:
inline void insert_blank_character();
template<unsigned int redbits, unsigned int greenbits, unsigned int bluebits>
- inline int32_t parse_sgr_38_48_parameters(vte::parser::Params const& params,
- unsigned int *index,
- bool might_contain_color_space_id);
+ inline bool seq_parse_sgr_color(vte::parser::Sequence const& seq,
+ unsigned int& idx,
+ uint32_t& color) const noexcept;
inline void move_cursor_backward(vte::grid::column_t columns);
inline void move_cursor_forward(vte::grid::column_t columns);
diff --git a/src/vteseq-list.hh b/src/vteseq-list.hh
index ddc666b..4393cb1 100644
--- a/src/vteseq-list.hh
+++ b/src/vteseq-list.hh
@@ -30,7 +30,6 @@ SEQUENCE_HANDLER(change_tek_cursor_color_bel)
SEQUENCE_HANDLER(change_tek_cursor_color_st)
SEQUENCE_HANDLER(change_tek_foreground_color_bel)
SEQUENCE_HANDLER(change_tek_foreground_color_st)
-SEQUENCE_HANDLER(character_attributes)
SEQUENCE_HANDLER(character_position_absolute)
SEQUENCE_HANDLER(cursor_back_tab)
SEQUENCE_HANDLER(cursor_backward)
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 38f4aa5..730217a 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -1786,277 +1786,106 @@ VteTerminalPrivate::seq_vertical_tab(vte::parser::Params const& params)
line_feed();
}
-/* Parse parameters of SGR 38, 48 or 58, starting at @index within @params.
- * If @might_contain_color_space_id, a true color sequence sequence is started, and after
- * its leading number "2" at least 4 more parameters are present, then there's an (ignored)
- * color_space_id before the three color components. See the comment below in
- * seq_character_attributes() to understand the different accepted formats.
- * Returns the color index, or -1 on error.
- * Increments @index to point to the last consumed parameter (not beyond). */
-
+/*
+ * Parse parameters of SGR 38, 48 or 58, starting at @index within @seq.
+ * Returns %true if @seq contained colour parameters at @index, or %false otherwise.
+ * In each case, @idx is set to last consumed parameter,
+ * and the colour is returned in @color.
+ *
+ * The format looks like:
+ * - 256 color indexed palette:
+ * - ^[[38:5:INDEXm (de jure standard: ITU-T T.416 / ISO/IEC 8613-6; we also allow and ignore further
parameters)
+ * - ^[[38;5;INDEXm (de facto standard, understood by probably all terminal emulators that support 256
colors)
+ * - true colors:
+ * - ^[[38:2:[id]:RED:GREEN:BLUE[:...]m (de jure standard: ITU-T T.416 / ISO/IEC 8613-6)
+ * - ^[[38:2:RED:GREEN:BLUEm (common misinterpretation of the standard, FIXME: stop supporting
it at some point)
+ * - ^[[38;2;RED;GREEN;BLUEm (de facto standard, understood by probably all terminal emulators
that support true colors)
+ * See bugs 685759 and 791456 for details.
+ */
template<unsigned int redbits, unsigned int greenbits, unsigned int bluebits>
-int32_t
-VteTerminalPrivate::parse_sgr_38_48_parameters(vte::parser::Params const& params,
- unsigned int *index,
- bool might_contain_color_space_id)
+bool
+VteTerminalPrivate::seq_parse_sgr_color(vte::parser::Sequence const& seq,
+ unsigned int &idx,
+ uint32_t& color) const noexcept
{
- auto n_params = params.size();
- if (*index < n_params) {
- int param0;
- if (G_UNLIKELY(!params.number_at_unchecked(*index, param0)))
- return -1;
+ /* Note that we don't have to check if the index is after the end of
+ * the parameters list, since dereferencing is safe and returns -1.
+ */
- switch (param0) {
+ if (seq.param_nonfinal(idx)) {
+ /* Colon version */
+ switch (seq.param(++idx)) {
case 2: {
- if (G_UNLIKELY(*index + 3 >= n_params))
- return -1;
- if (might_contain_color_space_id && *index + 5 <= n_params)
- *index += 1;
-
- int param1, param2, param3;
- if (G_UNLIKELY(!params.number_at_unchecked(*index + 1, param1) ||
- !params.number_at_unchecked(*index + 2, param2) ||
- !params.number_at_unchecked(*index + 3, param3)))
- return -1;
-
- if (G_UNLIKELY (param1 < 0 || param1 >= 256 || param2 < 0 || param2 >= 256 || param3
< 0 || param3 >= 256))
- return -1;
- *index += 3;
-
- return VTE_RGB_COLOR(redbits, greenbits, bluebits, param1, param2, param3);
+ auto const n = seq.next(idx) - idx;
+ if (n < 4)
+ return false;
+ if (n > 4) {
+ /* Consume a colourspace parameter; it must be default */
+ if (!seq.param_default(++idx))
+ return false;
+ }
+
+ int red = seq.param(++idx);
+ int green = seq.param(++idx);
+ int blue = seq.param(++idx);
+ if ((red & 0xff) != red ||
+ (green & 0xff) != green ||
+ (blue & 0xff) != blue)
+ return false;
+
+ color = VTE_RGB_COLOR(redbits, greenbits, bluebits, red, green, blue);
+ return true;
}
case 5: {
- int param1;
- if (G_UNLIKELY(!params.number_at(*index + 1, param1)))
- return -1;
-
- if (G_UNLIKELY(param1 < 0 || param1 >= 256))
- return -1;
- *index += 1;
- return param1;
+ auto const n = seq.next(idx) - idx;
+ if (n < 2)
+ return false;
+
+ int v = seq.param(++idx);
+ if (v < 0 || v >= 256)
+ return false;
+
+ color = (uint32_t)v;
+ return true;
}
- }
- }
- return -1;
-}
+ }
+ } else {
+ /* Semicolon version */
-/* Handle ANSI color setting and related stuffs (SGR).
- * @params contains the values split at semicolons, with sub arrays splitting at colons
- * wherever colons were encountered. */
-void
-VteTerminalPrivate::seq_character_attributes(vte::parser::Params const& params)
-{
- /* Step through each numeric parameter. */
- auto n_params = params.size();
- unsigned int i;
- for (i = 0; i < n_params; i++) {
- /* If this parameter is an array, it can be a fully colon separated 38 or 48
- * (see below for details). */
- if (G_UNLIKELY(params.has_subparams_at_unchecked(i))) {
- auto subparams = params.subparams_at_unchecked(i);
-
- int param0, param1;
- if (G_UNLIKELY(!subparams.number_at(0, param0)))
- continue;
+ idx = seq.next(idx);
+ switch (seq.param(idx)) {
+ case 2: {
+ /* Consume 3 more parameters */
+ idx = seq.next(idx);
+ int red = seq.param(idx);
+ idx = seq.next(idx);
+ int green = seq.param(idx);
+ idx = seq.next(idx);
+ int blue = seq.param(idx);
+
+ if ((red & 0xff) != red ||
+ (green & 0xff) != green ||
+ (blue & 0xff) != blue)
+ return false;
+
+ color = VTE_RGB_COLOR(redbits, greenbits, bluebits, red, green, blue);
+ return true;
+ }
+ case 5: {
+ /* Consume 1 more parameter */
+ idx = seq.next(idx);
+ int v = seq.param(idx);
- switch (param0) {
- case 4:
- if (subparams.number_at(1, param1) && param1 >= 0 && param1 <= 3)
- m_defaults.attr.set_underline(param1);
- break;
- case 38: {
- unsigned int index = 1;
- auto color = parse_sgr_38_48_parameters<8, 8, 8>(subparams, &index, true);
- if (G_LIKELY (color != -1))
- m_defaults.attr.set_fore(color);
- break;
- }
- case 48: {
- unsigned int index = 1;
- auto color = parse_sgr_38_48_parameters<8, 8, 8>(subparams, &index, true);
- if (G_LIKELY (color != -1))
- m_defaults.attr.set_back(color);
- break;
- }
- case 58: {
- unsigned int index = 1;
- auto color = parse_sgr_38_48_parameters<4, 5, 4>(subparams, &index, true);
- if (G_LIKELY (color != -1))
- m_defaults.attr.set_deco(color);
- break;
- }
- }
+ if ((v & 0xff) != v)
+ return false;
- continue;
- }
- /* If this parameter is not a number either, skip it. */
- int param;
- if (!params.number_at_unchecked(i, param))
- continue;
+ color = (uint32_t)v;
+ return true;
+ }
+ }
+ }
- switch (param) {
- case -1:
- case 0:
- reset_default_attributes(false);
- break;
- case 1:
- m_defaults.attr.set_bold(true);
- break;
- case 2:
- m_defaults.attr.set_dim(true);
- break;
- case 3:
- m_defaults.attr.set_italic(true);
- break;
- case 4:
- m_defaults.attr.set_underline(1);
- break;
- case 5:
- m_defaults.attr.set_blink(true);
- break;
- case 7:
- m_defaults.attr.set_reverse(true);
- break;
- case 8:
- m_defaults.attr.set_invisible(true);
- break;
- case 9:
- m_defaults.attr.set_strikethrough(true);
- break;
- case 21:
- m_defaults.attr.set_underline(2);
- break;
- case 22: /* ECMA 48. */
- m_defaults.attr.unset(VTE_ATTR_BOLD_MASK | VTE_ATTR_DIM_MASK);
- break;
- case 23:
- m_defaults.attr.set_italic(false);
- break;
- case 24:
- m_defaults.attr.set_underline(0);
- break;
- case 25:
- m_defaults.attr.set_blink(false);
- break;
- case 27:
- m_defaults.attr.set_reverse(false);
- break;
- case 28:
- m_defaults.attr.set_invisible(false);
- break;
- case 29:
- m_defaults.attr.set_strikethrough(false);
- break;
- case 30:
- case 31:
- case 32:
- case 33:
- case 34:
- case 35:
- case 36:
- case 37:
- m_defaults.attr.set_fore(VTE_LEGACY_COLORS_OFFSET + (param - 30));
- break;
- case 38:
- case 48:
- case 58:
- {
- /* The format looks like:
- * - 256 color indexed palette:
- * - ^[[38:5:INDEXm (de jure standard: ITU-T T.416 / ISO/IEC 8613-6; we also
allow and ignore further parameters)
- * - ^[[38;5;INDEXm (de facto standard, understood by probably all terminal
emulators that support 256 colors)
- * - true colors:
- * - ^[[38:2:[id]:RED:GREEN:BLUE[:...]m (de jure standard: ITU-T T.416 / ISO/IEC
8613-6)
- * - ^[[38:2:RED:GREEN:BLUEm (common misinterpretation of the
standard, FIXME: stop supporting it at some point)
- * - ^[[38;2;RED;GREEN;BLUEm (de facto standard, understood by
probably all terminal emulators that support true colors)
- * See bugs 685759 and 791456 for details.
- * The colon version was handled above separately.
- * This branch here is reached when the separators are semicolons. */
- if ((i + 1) < n_params) {
- ++i;
- int32_t color;
- switch (param) {
- case 38:
- color = parse_sgr_38_48_parameters<8 ,8 ,8>(params, &i, false);
- if (G_LIKELY (color != -1))
- m_defaults.attr.set_fore(color);
- break;
- case 48:
- color = parse_sgr_38_48_parameters<8, 8, 8>(params, &i, false);
- if (G_LIKELY (color != -1))
- m_defaults.attr.set_back(color);
- break;
- case 58:
- color = parse_sgr_38_48_parameters<4, 5, 4>(params, &i, false);
- g_printerr("Parsed semicoloned deco colour: %x\n", color);
- if (G_LIKELY (color != -1))
- m_defaults.attr.set_deco(color);
- break;
- }
- }
- break;
- }
- case 39:
- /* default foreground */
- m_defaults.attr.set_fore(VTE_DEFAULT_FG);
- break;
- case 40:
- case 41:
- case 42:
- case 43:
- case 44:
- case 45:
- case 46:
- case 47:
- m_defaults.attr.set_back(VTE_LEGACY_COLORS_OFFSET + (param - 40));
- break;
- /* case 48: was handled above at 38 to avoid code duplication */
- case 49:
- /* default background */
- m_defaults.attr.set_back(VTE_DEFAULT_BG);
- break;
- case 53:
- m_defaults.attr.set_overline(true);
- break;
- case 55:
- m_defaults.attr.set_overline(false);
- break;
- /* case 58: was handled above at 38 to avoid code duplication */
- case 59:
- /* default decoration color, that is, same as the cell's foreground */
- m_defaults.attr.set_deco(VTE_DEFAULT_FG);
- break;
- case 90:
- case 91:
- case 92:
- case 93:
- case 94:
- case 95:
- case 96:
- case 97:
- m_defaults.attr.set_fore(VTE_LEGACY_COLORS_OFFSET + (param - 90) +
- VTE_COLOR_BRIGHT_OFFSET);
- break;
- case 100:
- case 101:
- case 102:
- case 103:
- case 104:
- case 105:
- case 106:
- case 107:
- m_defaults.attr.set_back(VTE_LEGACY_COLORS_OFFSET + (param - 100) +
- VTE_COLOR_BRIGHT_OFFSET);
- break;
- }
- }
- /* If we had no parameters, default to the defaults. */
- if (i == 0) {
- reset_default_attributes(false);
- }
- /* Save the new colors. */
- m_color_defaults.attr.copy_colors(m_defaults.attr);
- m_fill_defaults.attr.copy_colors(m_defaults.attr);
+ return false;
}
/* Move the cursor to the given column in the top row, 1-based. */
@@ -5598,130 +5427,131 @@ VteTerminalPrivate::SGR(vte::parser::Sequence const& seq)
/*
* SGR - select-graphics-rendition
*/
-#if 0
- struct vte_color *dst;
- unsigned int i, code;
- int v;
+ auto const n_params = seq.size();
- if (seq->n_args < 1) {
- memset(&screen->state.attr, 0, sizeof(screen->state.attr));
- return 0;
- }
+ /* If we had no parameters, default to the defaults. */
+ if (n_params == 0) {
+ reset_default_attributes(false);
+ return;
+ }
- for (i = 0; i < seq->n_args; ++i) {
- v = seq->args[i];
- switch (v) {
+ for (unsigned int i = 0; i < n_params; i = seq.next(i)) {
+ auto const param = seq.param(i);
+ switch (param) {
+ case -1:
+ case 0:
+ reset_default_attributes(false);
+ break;
case 1:
- screen->state.attr.bold = 1;
+ m_defaults.attr.set_bold(true);
+ break;
+ case 2:
+ m_defaults.attr.set_dim(true);
break;
case 3:
- screen->state.attr.italic = 1;
+ m_defaults.attr.set_italic(true);
break;
- case 4:
- screen->state.attr.underline = 1;
+ case 4: {
+ unsigned int v = 1;
+ /* If we have a subparameter, get it */
+ if (seq.param_nonfinal(i)) {
+ v = seq.param(i + 1, 1, 0, 3);
+ }
+ m_defaults.attr.set_underline(v);
break;
+ }
case 5:
- screen->state.attr.blink = 1;
+ m_defaults.attr.set_blink(true);
break;
case 7:
- screen->state.attr.inverse = 1;
+ m_defaults.attr.set_reverse(true);
break;
case 8:
- screen->state.attr.hidden = 1;
+ m_defaults.attr.set_invisible(true);
break;
- case 22:
- screen->state.attr.bold = 0;
+ case 9:
+ m_defaults.attr.set_strikethrough(true);
+ break;
+ case 21:
+ m_defaults.attr.set_underline(2);
+ break;
+ case 22: /* ECMA 48. */
+ m_defaults.attr.unset(VTE_ATTR_BOLD_MASK | VTE_ATTR_DIM_MASK);
break;
case 23:
- screen->state.attr.italic = 0;
+ m_defaults.attr.set_italic(false);
break;
case 24:
- screen->state.attr.underline = 0;
+ m_defaults.attr.set_underline(0);
break;
case 25:
- screen->state.attr.blink = 0;
+ m_defaults.attr.set_blink(false);
break;
case 27:
- screen->state.attr.inverse = 0;
+ m_defaults.attr.set_reverse(false);
break;
case 28:
- screen->state.attr.hidden = 0;
+ m_defaults.attr.set_invisible(false);
+ break;
+ case 29:
+ m_defaults.attr.set_strikethrough(false);
break;
case 30 ... 37:
- screen->state.attr.fg.ccode = v - 30 +
- VTE_CCODE_BLACK;
+ m_defaults.attr.set_fore(VTE_LEGACY_COLORS_OFFSET + (param - 30));
break;
+ case 38: {
+ uint32_t fore;
+ if (G_LIKELY((seq_parse_sgr_color<8, 8, 8>(seq, i, fore))))
+ m_defaults.attr.set_fore(fore);
+ break;
+ }
case 39:
- screen->state.attr.fg.ccode = 0;
+ /* default foreground */
+ m_defaults.attr.set_fore(VTE_DEFAULT_FG);
break;
case 40 ... 47:
- screen->state.attr.bg.ccode = v - 40 +
- VTE_CCODE_BLACK;
+ m_defaults.attr.set_back(VTE_LEGACY_COLORS_OFFSET + (param - 40));
+ break;
+ case 48: {
+ uint32_t back;
+ if (G_LIKELY((seq_parse_sgr_color<8, 8, 8>(seq, i, back))))
+ m_defaults.attr.set_back(back);
break;
+ }
case 49:
- screen->state.attr.bg.ccode = 0;
+ /* default background */
+ m_defaults.attr.set_back(VTE_DEFAULT_BG);
break;
- case 90 ... 97:
- screen->state.attr.fg.ccode = v - 90 +
- VTE_CCODE_LIGHT_BLACK;
+ case 53:
+ m_defaults.attr.set_overline(true);
break;
- case 100 ... 107:
- screen->state.attr.bg.ccode = v - 100 +
- VTE_CCODE_LIGHT_BLACK;
+ case 55:
+ m_defaults.attr.set_overline(false);
break;
- case 38:
- /* fallthrough */
- case 48:
-
- if (v == 38)
- dst = &screen->state.attr.fg;
- else
- dst = &screen->state.attr.bg;
-
- ++i;
- if (i >= seq->n_args)
- break;
-
- switch (seq->args[i]) {
- case 2:
- /* 24bit-color support */
-
- i += 3;
- if (i >= seq->n_args)
- break;
-
- dst->ccode = VTE_CCODE_RGB;
- dst->red = (seq->args[i - 2] >= 0) ? seq->args[i - 2] : 0;
- dst->green = (seq->args[i - 1] >= 0) ? seq->args[i - 1] : 0;
- dst->blue = (seq->args[i] >= 0) ? seq->args[i] : 0;
-
- break;
- case 5:
- /* 256-color support */
-
- ++i;
- if (i >= seq->n_args || seq->args[i] < 0)
- break;
-
- dst->ccode = VTE_CCODE_256;
- code = seq->args[i];
- dst->c256 = code < 256 ? code : 0;
-
- break;
- }
-
+ case 58: {
+ uint32_t deco;
+ if (G_LIKELY((seq_parse_sgr_color<4, 5, 4>(seq, i, deco))))
+ m_defaults.attr.set_deco(deco);
break;
- case -1:
- /* fallthrough */
- case 0:
- memset(&screen->state.attr, 0,
- sizeof(screen->state.attr));
+ }
+ case 59:
+ /* default decoration color, that is, same as the cell's foreground */
+ m_defaults.attr.set_deco(VTE_DEFAULT_FG);
+ break;
+ case 90 ... 97:
+ m_defaults.attr.set_fore(VTE_LEGACY_COLORS_OFFSET + (param - 90) +
+ VTE_COLOR_BRIGHT_OFFSET);
+ break;
+ case 100 ... 107:
+ m_defaults.attr.set_back(VTE_LEGACY_COLORS_OFFSET + (param - 100) +
+ VTE_COLOR_BRIGHT_OFFSET);
break;
}
}
-#endif
- seq_character_attributes(seq);
+ /* Save the new colors. */
+ m_color_defaults.attr.copy_colors(m_defaults.attr);
+ m_fill_defaults.attr.copy_colors(m_defaults.attr);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]