[vte] emulation: Implement OSC 5
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] emulation: Implement OSC 5
- Date: Tue, 27 Mar 2018 17:47:21 +0000 (UTC)
commit 32243017bc520c512eaca79d7664ef5654c9f180
Author: Christian Persch <chpe src gnome org>
Date: Tue Mar 27 19:40:13 2018 +0200
emulation: Implement OSC 5
https://bugzilla.gnome.org/show_bug.cgi?id=722751
src/vteinternal.hh | 18 +++++-
src/vteseq.cc | 155 ++++++++++++++++++++++++++++++++++++----------------
src/vtetypes.hh | 4 +
3 files changed, 127 insertions(+), 50 deletions(-)
---
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 14e1bfe..a7bfeea 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -1295,10 +1295,23 @@ public:
char const* format,
...) noexcept G_GNUC_PRINTF(5, 6);
+ /* OSC handler helpers */
+ bool get_osc_color_index(int osc,
+ int value,
+ int& index) const noexcept;
+ bool set_color_index(vte::parser::Sequence const& seq,
+ vte::parser::StringTokeniser::const_iterator& token,
+ vte::parser::StringTokeniser::const_iterator const& endtoken,
+ int number,
+ int index,
+ int index_fallback,
+ int osc) noexcept;
+
/* OSC handlers */
void set_color(vte::parser::Sequence const& seq,
vte::parser::StringTokeniser::const_iterator& token,
- vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept;
+ vte::parser::StringTokeniser::const_iterator const& endtoken,
+ int osc) noexcept;
void set_special_color(vte::parser::Sequence const& seq,
vte::parser::StringTokeniser::const_iterator& token,
vte::parser::StringTokeniser::const_iterator const& endtoken,
@@ -1307,7 +1320,8 @@ public:
int osc) noexcept;
void reset_color(vte::parser::Sequence const& seq,
vte::parser::StringTokeniser::const_iterator& token,
- vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept;
+ vte::parser::StringTokeniser::const_iterator const& endtoken,
+ int osc) noexcept;
void set_current_directory_uri(vte::parser::Sequence const& seq,
vte::parser::StringTokeniser::const_iterator& token,
vte::parser::StringTokeniser::const_iterator const& endtoken)
noexcept;
diff --git a/src/vteseq.cc b/src/vteseq.cc
index e527b08..43a87d1 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -1339,10 +1339,46 @@ VteTerminalPrivate::delete_lines(vte::grid::row_t param)
m_text_deleted_flag = TRUE;
}
+bool
+VteTerminalPrivate::get_osc_color_index(int osc,
+ int value,
+ int& index) const noexcept
+{
+ if (value < 0)
+ return false;
+
+ if (osc == VTE_OSC_XTERM_SET_COLOR ||
+ osc == VTE_OSC_XTERM_RESET_COLOR) {
+ if (value < VTE_DEFAULT_FG) {
+ index = value;
+ return true;
+ }
+
+ index = value - VTE_DEFAULT_FG;
+ } else {
+ index = value;
+ }
+
+ /* Translate OSC 5 numbers to color index.
+ *
+ * We return -1 for known but umimplemented special colors
+ * so that we can send a dummy reply when queried.
+ */
+ switch (index) {
+ case 0: index = VTE_BOLD_FG; return true; /* Bold */
+ case 1: index = -1; return true; /* Underline */
+ case 2: index = -1; return true; /* Blink */
+ case 3: index = -1; return true; /* Reverse */
+ case 4: index = -1; return true; /* Italic */
+ default: return false;
+ }
+}
+
void
VteTerminalPrivate::set_color(vte::parser::Sequence const& seq,
vte::parser::StringTokeniser::const_iterator& token,
- vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept
+ vte::parser::StringTokeniser::const_iterator const& endtoken,
+ int osc) noexcept
{
bool any_changed = false;
@@ -1353,80 +1389,101 @@ VteTerminalPrivate::set_color(vte::parser::Sequence const& seq,
if (++token == endtoken)
break;
+ int index;
if (!has_value ||
- value < 0 ||
- value >= VTE_DEFAULT_FG) {
+ !get_osc_color_index(osc, value, index)) {
++token;
continue;
}
- auto const str = *token;
-
- if (str == "?"s) {
- auto c = get_color(value);
- g_assert_nonnull(c);
-
- reply(seq, VTE_REPLY_OSC, {}, "4;%d;rgb:%04x/%04x/%04x",
- value, c->red, c->green, c->blue);
- } else {
- vte::color::rgb color;
- if (color.parse(str.data())) {
- set_color(value, VTE_COLOR_SOURCE_ESCAPE, color);
- any_changed = true;
- }
- }
-
+ any_changed |= set_color_index(seq, token, endtoken, value, index, -1, osc);
++token;
}
/* emit the refresh as the palette has changed and previous
- * renders need to be updated. */
+ * renders need to be updated.
+ */
if (any_changed)
emit_refresh_window();
}
-void
-VteTerminalPrivate::set_special_color(vte::parser::Sequence const& seq,
- vte::parser::StringTokeniser::const_iterator& token,
- vte::parser::StringTokeniser::const_iterator const& endtoken,
- int index,
- int index_fallback,
- int osc)
+bool
+VteTerminalPrivate::set_color_index(vte::parser::Sequence const& seq,
+ vte::parser::StringTokeniser::const_iterator& token,
+ vte::parser::StringTokeniser::const_iterator const& endtoken,
+ int number,
+ int index,
+ int index_fallback,
+ int osc)
{
- if (token == endtoken)
- return;
+ bool palette_changed = false;
auto const str = *token;
+
if (str == "?"s) {
- auto c = get_color(index);
- if (c == nullptr && index_fallback != -1)
- c = get_color(index_fallback);
- g_assert_nonnull(c);
+ vte::color::rgb color{0, 0, 0};
+ if (index != -1) {
+ auto const* c = get_color(index);
+ if (c == nullptr && index_fallback != -1)
+ c = get_color(index_fallback);
+ if (c != nullptr)
+ color = *c;
+ }
- reply(seq, VTE_REPLY_OSC, {}, "%d;rgb:%04x/%04x/%04x",
- osc, c->red, c->green, c->blue);
+ if (number != -1)
+ reply(seq, VTE_REPLY_OSC, {}, "%d;%d;rgb:%04x/%04x/%04x",
+ osc, number, color.red, color.green, color.blue);
+ else
+ reply(seq, VTE_REPLY_OSC, {}, "%d;rgb:%04x/%04x/%04x",
+ osc, color.red, color.green, color.blue);
} else {
vte::color::rgb color;
- if (color.parse(str.data())) {
+
+ if (index != -1 &&
+ color.parse(str.data())) {
set_color(index, VTE_COLOR_SOURCE_ESCAPE, color);
- /* emit the refresh as the palette has changed and previous
- * renders need to be updated. */
- emit_refresh_window();
+ palette_changed = true;
}
}
+
+ return palette_changed;
+}
+
+void
+VteTerminalPrivate::set_special_color(vte::parser::Sequence const& seq,
+ vte::parser::StringTokeniser::const_iterator& token,
+ vte::parser::StringTokeniser::const_iterator const& endtoken,
+ int index,
+ int index_fallback,
+ int osc) noexcept
+{
+ if (token == endtoken)
+ return;
+
+ /* emit the refresh as the palette has changed and previous
+ * renders need to be updated.
+ */
+ if (set_color_index(seq, token, endtoken, -1, index, index_fallback, osc))
+ emit_refresh_window();
}
void
VteTerminalPrivate::reset_color(vte::parser::Sequence const& seq,
vte::parser::StringTokeniser::const_iterator& token,
- vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept
+ vte::parser::StringTokeniser::const_iterator const& endtoken,
+ int osc) noexcept
{
/* Empty param? Reset all */
if (token == endtoken ||
token.size_remaining() == 0) {
- for (unsigned int idx = 0; idx < VTE_DEFAULT_FG; idx++)
- reset_color(idx, VTE_COLOR_SOURCE_ESCAPE);
+ if (osc == VTE_OSC_XTERM_RESET_COLOR) {
+ for (unsigned int idx = 0; idx < VTE_DEFAULT_FG; idx++)
+ reset_color(idx, VTE_COLOR_SOURCE_ESCAPE);
+ }
+
+ reset_color(VTE_BOLD_FG, VTE_COLOR_SOURCE_ESCAPE);
+ /* Add underline/blink/reverse/italic here if/when implemented */
/* emit the refresh as the palette has changed and previous
* renders need to be updated. */
@@ -1441,8 +1498,10 @@ VteTerminalPrivate::reset_color(vte::parser::Sequence const& seq,
if (!token.number(value))
continue;
- if (0 <= value && value < VTE_DEFAULT_FG) {
- reset_color(value, VTE_COLOR_SOURCE_ESCAPE);
+ int index;
+ if (get_osc_color_index(osc, value, index) &&
+ index != -1) {
+ reset_color(index, VTE_COLOR_SOURCE_ESCAPE);
any_changed = true;
}
@@ -6261,7 +6320,8 @@ VteTerminalPrivate::OSC(vte::parser::Sequence const& seq)
}
case VTE_OSC_XTERM_SET_COLOR:
- set_color(seq, it, cend);
+ case VTE_OSC_XTERM_SET_COLOR_SPECIAL:
+ set_color(seq, it, cend, osc);
break;
case VTE_OSC_XTERM_SET_COLOR_TEXT_FG:
@@ -6285,7 +6345,8 @@ VteTerminalPrivate::OSC(vte::parser::Sequence const& seq)
break;
case VTE_OSC_XTERM_RESET_COLOR:
- reset_color(seq, it, cend);
+ case VTE_OSC_XTERM_RESET_COLOR_SPECIAL:
+ reset_color(seq, it, cend, osc);
break;
case VTE_OSC_XTERM_RESET_COLOR_TEXT_FG:
@@ -6310,7 +6371,6 @@ VteTerminalPrivate::OSC(vte::parser::Sequence const& seq)
case VTE_OSC_XTERM_SET_ICON_TITLE:
case VTE_OSC_XTERM_SET_XPROPERTY:
- case VTE_OSC_XTERM_SET_COLOR_SPECIAL:
case VTE_OSC_XTERM_SET_COLOR_MOUSE_CURSOR_FG:
case VTE_OSC_XTERM_SET_COLOR_MOUSE_CURSOR_BG:
case VTE_OSC_XTERM_SET_COLOR_TEK_FG:
@@ -6319,7 +6379,6 @@ VteTerminalPrivate::OSC(vte::parser::Sequence const& seq)
case VTE_OSC_XTERM_LOGFILE:
case VTE_OSC_XTERM_SET_FONT:
case VTE_OSC_XTERM_SET_XSELECTION:
- case VTE_OSC_XTERM_RESET_COLOR_SPECIAL:
case VTE_OSC_XTERM_SET_COLOR_MODE:
case VTE_OSC_XTERM_RESET_COLOR_MOUSE_CURSOR_FG:
case VTE_OSC_XTERM_RESET_COLOR_MOUSE_CURSOR_BG:
diff --git a/src/vtetypes.hh b/src/vtetypes.hh
index 9551208..885c2fb 100644
--- a/src/vtetypes.hh
+++ b/src/vtetypes.hh
@@ -21,6 +21,8 @@
#include <gdk/gdk.h>
#include <errno.h>
+#include <cstdint>
+
#ifdef VTE_DEBUG
#define IFDEF_DEBUG(str) str
#else
@@ -153,6 +155,8 @@ namespace color {
rgb(PangoColor const& c) { *static_cast<PangoColor*>(this) = c; }
rgb(GdkRGBA const* c);
rgb(GdkRGBA const& c) : rgb(&c) { }
+ rgb(uint16_t r, uint16_t g, uint16_t b)
+ : PangoColor{r, g, b} { }
bool parse(char const* spec);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]