[vte] emulation: Unify mode handling
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] emulation: Unify mode handling
- Date: Tue, 27 Mar 2018 17:44:19 +0000 (UTC)
commit b0bb1540a5e1321aa4944310416b3d072596a002
Author: Christian Persch <chpe src gnome org>
Date: Tue Mar 27 19:40:12 2018 +0200
emulation: Unify mode handling
src/Makefile.am | 23 ++-
src/debug.cc | 1 +
src/debug.h | 1 +
src/modes-ecma.hh | 65 ++++++
src/modes-private.hh | 250 ++++++++++++++++++++
src/modes-test.cc | 90 ++++++++
src/modes.hh | 250 ++++++++++++++++++++
src/vte.cc | 131 ++++-------
src/vteinternal.hh | 68 ++----
src/vteseq.cc | 612 +++++++++++++++-----------------------------------
10 files changed, 934 insertions(+), 557 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index c82f02f..a17d441 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,6 +55,9 @@ libvte_@VTE_API_MAJOR_VERSION@_@VTE_API_MINOR_VERSION@_la_SOURCES = \
iso2022.h \
keymap.cc \
keymap.h \
+ modes.hh \
+ modes-ecma.hh \
+ modes-private.hh \
parser.cc \
parser.hh \
parser-arg.hh \
@@ -175,7 +178,7 @@ vteresources.cc: vte.gresource.xml Makefile $(shell $(GLIB_COMPILE_RESOURCES) --
# Misc unit tests and utilities
-noinst_PROGRAMS += parser-cat slowcat test-parser
+noinst_PROGRAMS += parser-cat slowcat test-modes test-parser
noinst_SCRIPTS = decset osc window
EXTRA_DIST += $(noinst_SCRIPTS)
@@ -196,6 +199,7 @@ dist_check_SCRIPTS = \
$(NULL)
TESTS = \
+ test-modes \
test-parser \
reaper \
test-vtetypes \
@@ -289,6 +293,23 @@ test_parser_LDADD = \
$(VTE_LIBS) \
$(NULL)
+test_modes_SOURCES = \
+ modes-test.cc \
+ modes.hh \
+ modes-ecma.hh \
+ modes-private.hh \
+ $(NULL)
+test_modes_CPPFLAGS = \
+ -I$(builddir) \
+ -I$(srcdir) \
+ $(AM_CPPFLAGS)
+test_modes_CXXFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(AM_CXXFLAGS)
+test_modes_LDADD = \
+ $(GLIB_LIBS) \
+ $(NULL)
+
test_vtetypes_SOURCES = \
vtetypes.cc \
vtetypes.hh \
diff --git a/src/debug.cc b/src/debug.cc
index 1352f8b..0101f69 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -55,6 +55,7 @@ _vte_debug_init(void)
{ "resize", VTE_DEBUG_RESIZE },
{ "regex", VTE_DEBUG_REGEX },
{ "hyperlink", VTE_DEBUG_HYPERLINK },
+ { "modes", VTE_DEBUG_MODES },
};
_vte_debug_flags = g_parse_debug_string (g_getenv("VTE_DEBUG"),
diff --git a/src/debug.h b/src/debug.h
index e156477..e5222bd 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -62,6 +62,7 @@ typedef enum {
VTE_DEBUG_RESIZE = 1 << 22,
VTE_DEBUG_REGEX = 1 << 23,
VTE_DEBUG_HYPERLINK = 1 << 24,
+ VTE_DEBUG_MODES = 1 << 25,
} VteDebugFlags;
void _vte_debug_init(void);
diff --git a/src/modes-ecma.hh b/src/modes-ecma.hh
new file mode 100644
index 0000000..68d7876
--- /dev/null
+++ b/src/modes-ecma.hh
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 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
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modes for SM_ECMA/RM_ECMA.
+ *
+ * Most of these are not implemented in VTE.
+ *
+ * References: ECMA-48 § 7
+ * WY370
+ */
+
+MODE(IRM, 4)
+MODE(SRM, 12)
+
+/* Unsupported */
+
+MODE_FIXED(GATM, 1, ALWAYS_RESET)
+MODE_FIXED(KAM, 2, ALWAYS_RESET)
+MODE_FIXED(CRM, 3, ALWAYS_RESET)
+MODE_FIXED(SRTM, 5, ALWAYS_RESET)
+MODE_FIXED(ERM, 6, ALWAYS_RESET)
+MODE_FIXED(VEM, 7, ALWAYS_RESET)
+MODE_FIXED(BDSM, 8, ALWAYS_RESET)
+MODE_FIXED(DCSM, 9, ALWAYS_RESET)
+MODE_FIXED(HEM, 10, ALWAYS_RESET)
+MODE_FIXED(PUM, 11, ALWAYS_RESET) /* ECMA-48 § F.4.1 Deprecated */
+MODE_FIXED(FEAM, 13, ALWAYS_RESET)
+MODE_FIXED(FETM, 14, ALWAYS_RESET)
+MODE_FIXED(MATM, 15, ALWAYS_RESET)
+MODE_FIXED(TTM, 16, ALWAYS_RESET)
+MODE_FIXED(SATM, 17, ALWAYS_RESET)
+MODE_FIXED(TSM, 18, ALWAYS_RESET)
+MODE_FIXED(EBM, 19, ALWAYS_RESET) /* ECMA-48 § F.5.1 Removed */
+MODE_FIXED(LNM, 20, ALWAYS_RESET) /* ECMA-48 § F.5.2 Removed */
+MODE_FIXED(GRCM, 21, ALWAYS_SET)
+MODE_FIXED(ZDM, 22, ALWAYS_RESET) /* ECMA-48 § F.4.2 Deprecated */
+
+#if 0
+MODE_FIXED(WYDSCM, 30, ALWAYS_SET)
+MODE_FIXED(WYSTLINM, 31, ALWAYS_RESET)
+MODE_FIXED(WYCRTSAVM, 32, ALWAYS_RESET)
+MODE_FIXED(WYSTCURM, 33, ?)
+MODE_FIXED(WYULCURM, 34, ?)
+MODE_FIXED(WYCLRM, 35, ALWAYS_SET)
+MODE_FIXED(WYDELKM, 36, ALWAYS_RESET) /* Same as DECBKM */
+MODE_FIXED(WYGATM, 37, ?)
+MODE_FIXED(WYTEXM, 38, ?)
+MODE_FIXED(WYEXTDM, 40, ALWAYS_SET)
+MODE_FIXED(WYASCII, 42, ALWAYS_SET)
+#endif
diff --git a/src/modes-private.hh b/src/modes-private.hh
new file mode 100644
index 0000000..f7a26e7
--- /dev/null
+++ b/src/modes-private.hh
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 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
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modes for SM_DEC/RM_DEC.
+ *
+ * Most of these are not implemented in VTE.
+ *
+ * References: VT525
+ * XTERM
+ * KITTY
+ * MINTTY
+ * MLTERM
+ * RLogin
+ * URXVT
+ * WY370
+ */
+
+/* Supported modes: */
+
+/* DEC */
+
+/*
+ * DECCKM - cursor keys mode
+ */
+MODE(DEC_APPLICATION_CURSOR_KEYS, 1)
+
+/*
+ * DECCOLM: 132 column mode
+ */
+MODE(DEC_132_COLUMN, 3)
+
+/*
+ * DECSCNM - screen mode
+ */
+MODE(DEC_REVERSE_IMAGE, 5)
+
+/*
+ * DECOM - origin mode
+ */
+MODE(DEC_ORIGIN, 6)
+
+/*
+ * DECAWM - auto wrap mode
+ */
+MODE(DEC_AUTOWRAP, 7)
+
+/*
+ * DECTCEM - text cursor enable
+ */
+MODE(DEC_TEXT_CURSOR, 25)
+
+/*
+ * DECNKM - numeric/application keypad mode
+ */
+MODE(DEC_APPLICATION_KEYPAD, 66)
+
+/* XTERM */
+
+MODE(XTERM_MOUSE_X10, 9)
+MODE(XTERM_DECCOLM, 40)
+MODE(XTERM_ALTBUF, 47)
+MODE(XTERM_MOUSE_VT220, 1000)
+MODE(XTERM_MOUSE_VT220_HIGHLIGHT, 1001)
+MODE(XTERM_MOUSE_BUTTON_EVENT, 1002)
+MODE(XTERM_MOUSE_ANY_EVENT, 1003)
+MODE(XTERM_FOCUS, 1004)
+MODE(XTERM_MOUSE_EXT_SGR, 1006)
+MODE(XTERM_ALTBUF_SCROLL, 1007)
+MODE(XTERM_META_SENDS_ESCAPE, 1036)
+MODE(XTERM_OPT_ALTBUF, 1047)
+MODE(XTERM_SAVE_CURSOR, 1048)
+MODE(XTERM_OPT_ALTBUF_SAVE_CURSOR, 1049)
+MODE(XTERM_READLINE_BRACKETED_PASTE, 2004)
+
+/* URXVT */
+
+MODE(URXVT_MOUSE_EXT, 1015)
+
+/* Not supported modes: */
+
+/* DEC */
+
+MODE_FIXED(DECANM, 2, ALWAYS_SET)
+MODE_FIXED(DECSCLM, 4, ALWAYS_RESET)
+MODE_FIXED(DECARM, 8, ALWAYS_SET)
+MODE_FIXED(DECLTM, 11, ALWAYS_RESET)
+MODE_FIXED(DECEKEM, 16, ALWAYS_RESET)
+MODE_FIXED(DECCPFF, 18, ALWAYS_RESET)
+MODE_FIXED(DECPEX, 19, ALWAYS_RESET)
+MODE_FIXED(DECRLM, 34, ALWAYS_RESET)
+MODE_FIXED(DECHEBM, 35, ALWAYS_RESET)
+MODE_FIXED(DECHEM, 36, ALWAYS_RESET)
+MODE_FIXED(DECNRCM, 42, ALWAYS_RESET)
+MODE_FIXED(DECGEPM, 43, ALWAYS_RESET) /* from VT330 */
+/* MODE_FIXED(DECGPCM, 44, ALWAYS_RESET) * from VT330, conflicts with XTERM_MARGIN_BELL */
+/* MODE_FIXED(DECGPCS, 45, ALWAYS_RESET) * from VT330, conflicts with XTERM_REVERSE_WRAP */
+/* MODE_FIXED(DECGPBM, 46, ALWAYS_RESET) * from VT330, conflicts with XTERM_LOGGING */
+/* MODE_FIXED(DECGRPM, 47, ALWAYS_RESET) * from VT330, conflicts with XTERM_ALTBUF */
+MODE_FIXED(DEC131TM, 53, ALWAYS_RESET)
+MODE_FIXED(DECNAKB, 57, ALWAYS_RESET)
+/* MODE_FIXED(DECKKDM, 59, ALWAYS_SET) * Kanji/Katakana Display Mode, from VT382-Kanji */
+MODE_FIXED(DECHCCM, 60, ALWAYS_RESET)
+MODE_FIXED(DECVCCM, 61, ALWAYS_RESET)
+MODE_FIXED(DECPCCM, 64, ALWAYS_RESET)
+MODE_FIXED(DECBKM, 67, ALWAYS_RESET)
+MODE_FIXED(DECKBUM, 68, ALWAYS_RESET)
+MODE_FIXED(DECVSSM, 69, ALWAYS_RESET) /* aka DECLRMM */
+MODE_FIXED(DECXRLM, 73, ALWAYS_RESET)
+/* MODE_FIXED(DECSDM, 80, ALWAYS_RESET) ! Conflicts with WY161 */
+MODE_FIXED(DECKPM, 81, ALWAYS_RESET)
+MODE_FIXED(DECTHAISCM, 90, ALWAYS_RESET) /* Thai Space Compensating Mode, from VT382-Thai */
+MODE_FIXED(DECNCSM, 95, ALWAYS_RESET)
+MODE_FIXED(DECRLCM, 96, ALWAYS_RESET)
+MODE_FIXED(DECRCRTSM, 97, ALWAYS_RESET)
+MODE_FIXED(DECARSM, 98, ALWAYS_RESET)
+MODE_FIXED(DECMCM, 99, ALWAYS_RESET)
+MODE_FIXED(DECAAM, 100, ALWAYS_RESET)
+MODE_FIXED(DECANSM, 101, ALWAYS_RESET)
+MODE_FIXED(DECNULM, 102, ALWAYS_RESET)
+MODE_FIXED(DECHDPXM, 103, ALWAYS_RESET)
+MODE_FIXED(DECESKM, 104, ALWAYS_RESET)
+MODE_FIXED(DECOSCNM, 106, ALWAYS_RESET)
+MODE_FIXED(DECCAPSLK, 109, ALWAYS_RESET)
+MODE_FIXED(DECFWM, 111, ALWAYS_RESET)
+MODE_FIXED(DECRPL, 112, ALWAYS_RESET)
+MODE_FIXED(DECHWUM, 113, ALWAYS_RESET)
+MODE_FIXED(DECATCUM, 114, ALWAYS_RESET)
+MODE_FIXED(DECATCBM, 115, ALWAYS_RESET)
+MODE_FIXED(DECBBSM, 116, ALWAYS_RESET)
+MODE_FIXED(DECECM, 117, ALWAYS_RESET)
+
+/* DRCSTerm */
+/* Modes 8800…8804 */
+
+/* KITTY */
+
+MODE_FIXED(KITTY_STYLED_UNDERLINES, 2016, ALWAYS_SET)
+MODE_FIXED(KITTY_EXTENDED_KEYBOARD, 2017, ALWAYS_RESET)
+
+/* MinTTY */
+
+MODE_FIXED(MINTTY_REPORT_CJK_AMBIGUOUS_WIDTH, 7700, ALWAYS_RESET)
+MODE_FIXED(MINTTY_REPORT_SCROLL_MARKER_IN_CURRENT_LINE, 7711, ALWAYS_RESET)
+MODE_FIXED(MINTTY_APPLICATION_ESCAPE, 7727, ALWAYS_RESET)
+MODE_FIXED(MINTTY_ESCAPE_SENDS_FS, 7728, ALWAYS_RESET)
+MODE_FIXED(MINTTY_SIXEL_SCROLLING_END_POSITION, 7730, ALWAYS_RESET)
+MODE_FIXED(MINTTY_SCROLLBAR, 7766, ALWAYS_RESET)
+MODE_FIXED(MINTTY_REPORT_FONT_CHANGES, 7767, ALWAYS_RESET)
+MODE_FIXED(MINTTY_SHORTCUT_OVERRIDE, 7783, ALWAYS_RESET)
+MODE_FIXED(MINTTY_ALBUF_MOUSEWHEEL_TO_CURSORKEYS, 7786, ALWAYS_RESET)
+MODE_FIXED(MINTTY_MOUSEWHEEL_APPLICATION_KEYS, 7787, ALWAYS_RESET)
+MODE_FIXED(MINTTY_BIDI_DISABLE_IN_CURRENT_LINE, 7796, ALWAYS_RESET)
+MODE_FIXED(MINTTY_SIXEL_SCROLL_CURSOR_RIGHT, 8452, ALWAYS_RESET)
+/* MinTTY also knows mode 77096 'BIDI disable", and 77000..77031
+ * "Application control key" which are outside of the supported range
+ * for CSI parameters.
+ */
+
+/* RLogin */
+
+/* RLogin appears to use many modes
+ * [https://github.com/kmiya-culti/RLogin/blob/master/RLogin/TextRam.h#L131]:
+ * 1406..1415, 1420..1425, 1430..1434, 1436, 1452..1481,
+ * 8400..8406, 8416..8417, 8428..8429, 8435, 8437..8443,
+ * 8446..8458,
+ * and modes 7727, 7786, 8200 (home cursor on [ED 2]),
+ * 8800 (some weird Unicode plane 17 mapping?), 8840 (same as 8428).
+ *
+ * We're not going to implement them, but avoid these ranges
+ * when assigning new mode numbers.
+ *
+ * The following are the ones from RLogin that MLTerm knows about:
+ */
+
+/* MODE_FIXED(RLOGIN_APPLICATION_ESCAPE, 7727, ALWAYS_RESET) */
+/* MODE_FIXED(RLOGIN_MOUSEWHEEL_TO_CURSORKEYS, 7786, ALWAYS_RESET) */
+
+/* Ambiguous-width characters are wide (reset) or narrow (set) */
+MODE_FIXED(RLOGIN_AMBIGUOUS_WIDTH_CHARACTERS_NARROW, 8428, ALWAYS_RESET)
+
+/* MODE_FIXED(RLOGIN_CURSOR_TO_RIGHT_OF_SIXEL, 8452, ALWAYS_RESET) */
+
+/* XTERM also knows this one */
+/* MODE_FIXED(RLOGIN_SIXEL_SCROLL_CURSOR_RIGHT, 8452, ALWAYS_RESET) */
+
+/* RXVT */
+
+MODE_FIXED(RXVT_TOOLBAR, 10, ALWAYS_RESET)
+MODE_FIXED(RXVT_SCROLLBAR, 30, ALWAYS_RESET)
+/* MODE_FIXED(RXVT_SHIFT_KEYS, 35, ALWAYS_RESET) ! Conflicts with DECHEBM */
+MODE_FIXED(RXVT_SCROLL_OUTPUT, 1010, ALWAYS_RESET)
+MODE_FIXED(RXVT_SCROLL_KEYPRES, 1011, ALWAYS_RESET)
+/* Bold/blink uses normal (reset) or high intensity (set) colour */
+MODE_FIXED(RXVT_INTENSITY_STYLES, 1021, ALWAYS_SET)
+
+/* Wyse */
+
+MODE_FIXED(WYTEK, 38, ALWAYS_RESET)
+MODE_FIXED(WY161, 80, ALWAYS_RESET)
+MODE_FIXED(WY52, 83, ALWAYS_RESET)
+MODE_FIXED(WYENAT, 84, ALWAYS_RESET)
+MODE_FIXED(WYREPL, 85, ALWAYS_RESET)
+
+/* XTERM */
+
+MODE_FIXED(XTERM_ATT610_BLINK, 12, ALWAYS_RESET)
+MODE_FIXED(XTERM_CURSOR_BLINK, 13, ALWAYS_RESET)
+MODE_FIXED(XTERM_CURSOR_BLINK_XOR, 14, ALWAYS_RESET)
+MODE_FIXED(XTERM_CURSES_HACK, 41, ALWAYS_RESET)
+MODE_FIXED(XTERM_MARGIN_BELL, 44, ALWAYS_RESET)
+MODE_FIXED(XTERM_REVERSE_WRAP, 45, ALWAYS_RESET)
+MODE_FIXED(XTERM_LOGGING, 46, ALWAYS_RESET)
+MODE_FIXED(XTERM_MOUSE_EXT, 1005, ALWAYS_RESET)
+MODE_FIXED(XTERM_8BIT_META, 1034, ALWAYS_RESET)
+MODE_FIXED(XTERM_NUMLOCK, 1035, ALWAYS_RESET)
+MODE_FIXED(XTERM_DELETE_IS_DEL, 1037, ALWAYS_RESET)
+MODE_FIXED(XTERM_ALT_SENDS_ESCAPE, 1039, ALWAYS_RESET)
+MODE_FIXED(XTERM_KEEP_SELECTION, 1040, ALWAYS_RESET)
+MODE_FIXED(XTERM_KEEP_CLIPBOARD, 1044, ALWAYS_RESET)
+MODE_FIXED(XTERM_SELECT_TO_CLIPBOARD, 1041, ALWAYS_RESET)
+MODE_FIXED(XTERM_BELL_URGENT, 1042, ALWAYS_RESET)
+MODE_FIXED(XTERM_PRESENT_ON_BELL, 1043, ALWAYS_RESET)
+MODE_FIXED(XTERM_ALLOW_ALTBUF, 1046, ALWAYS_SET)
+MODE_FIXED(XTERM_FKEYS_TERMCAP, 1050, ALWAYS_RESET)
+MODE_FIXED(XTERM_FKEYS_SUN, 1051, ALWAYS_RESET)
+MODE_FIXED(XTERM_FKEYS_HP, 1052, ALWAYS_RESET)
+MODE_FIXED(XTERM_FKEYS_SCO, 1053, ALWAYS_RESET)
+MODE_FIXED(XTERM_FKEYS_LEGACY, 1060, ALWAYS_RESET)
+MODE_FIXED(XTERM_FKEYS_VT220, 1061, ALWAYS_RESET)
+MODE_FIXED(XTERM_SIXEL_PRIVATE_COLOR_REGISTERS, 1070, ALWAYS_SET)
+MODE_FIXED(XTERM_READLINE_BUTTON1_MOVE_POINT, 2001, ALWAYS_RESET)
+MODE_FIXED(XTERM_READLINE_BUTTON2_MOVE_POINT, 2002, ALWAYS_RESET)
+MODE_FIXED(XTERM_READLINE_DBLBUTTON3_DELETE, 2003, ALWAYS_RESET)
+MODE_FIXED(XTERM_READLINE_PASTE_QUOTE, 2005, ALWAYS_RESET)
+MODE_FIXED(XTERM_READLINE_PASTE_LITERAL_NL, 2006, ALWAYS_RESET)
diff --git a/src/modes-test.cc b/src/modes-test.cc
new file mode 100644
index 0000000..39f4cfb
--- /dev/null
+++ b/src/modes-test.cc
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 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
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include <glib.h>
+
+#include "modes.hh"
+
+static void
+test_modes_ecma(void)
+{
+ vte::terminal::modes::ECMA modes{};
+
+ g_assert_false(modes.IRM());
+ g_assert_true(modes.SRM());
+ modes.set_IRM(true);
+ g_assert_true(modes.IRM());
+ g_assert_true(modes.SRM());
+ modes.set_SRM(false);
+ g_assert_true(modes.IRM());
+ g_assert_false(modes.SRM());
+
+ vte::terminal::modes::ECMA copy{modes};
+ g_assert_cmpuint(copy.get_modes(), ==, modes.get_modes());
+ g_assert_cmpint(copy.IRM(), ==, modes.IRM());
+ g_assert_cmpint(copy.SRM(), ==, modes.SRM());
+
+ modes.reset();
+ g_assert_false(modes.IRM());
+ g_assert_true(modes.SRM());
+}
+
+static void
+test_modes_private(void)
+{
+ vte::terminal::modes::Private modes{};
+
+ g_assert_true(modes.DEC_AUTOWRAP());
+ g_assert_true(modes.XTERM_META_SENDS_ESCAPE());
+
+ g_assert_false(modes.XTERM_FOCUS());
+ modes.set_XTERM_FOCUS(true);
+ g_assert_true(modes.XTERM_FOCUS());
+ modes.push_saved(vte::terminal::modes::Private::eXTERM_FOCUS);
+ modes.set_XTERM_FOCUS(false);
+ g_assert_false(modes.XTERM_FOCUS());
+ bool set = modes.pop_saved(vte::terminal::modes::Private::eXTERM_FOCUS);
+ g_assert_true(set);
+ modes.set_XTERM_FOCUS(set);
+ g_assert_true(modes.XTERM_FOCUS());
+ modes.push_saved(vte::terminal::modes::Private::eXTERM_FOCUS);
+ modes.clear_saved();
+ set = modes.pop_saved(vte::terminal::modes::Private::eXTERM_FOCUS);
+ g_assert_false(set);
+}
+
+int
+main(int argc,
+ char* argv[])
+{
+ g_test_init(&argc, &argv, nullptr);
+
+ g_test_add_func("/vte/modes/ecma", test_modes_ecma);
+ g_test_add_func("/vte/modes/private", test_modes_private);
+
+ return g_test_run();
+}
diff --git a/src/modes.hh b/src/modes.hh
new file mode 100644
index 0000000..b7fe53f
--- /dev/null
+++ b/src/modes.hh
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 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
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+namespace vte {
+namespace terminal {
+namespace modes {
+
+#define VTE_MODES_MASK(shift) (1U << (shift))
+
+#define MODE_ACCESSOR(name) \
+ inline void set_##name(bool value) noexcept \
+ { \
+ set(e##name, value); \
+ } \
+ \
+ inline constexpr bool name() const noexcept \
+ { \
+ return get(e##name); \
+ }
+
+template <typename T>
+static inline void vte_modes_set_bool(T* modes,
+ unsigned int shift,
+ bool value)
+{
+ if (value)
+ *modes |= T(1U) << shift;
+ else
+ *modes &= ~(T(1U) << shift);
+}
+
+template <typename T>
+static constexpr inline bool vte_modes_get_bool(T modes,
+ unsigned int shift)
+{
+ return (modes >> shift) & 1U;
+}
+
+template <typename T>
+static constexpr inline bool vte_modes_unset_bool(T* modes,
+ unsigned int shift)
+{
+ bool set = vte_modes_get_bool<T>(*modes, shift);
+ vte_modes_set_bool<T>(modes, shift, false);
+ return set;
+}
+
+template <typename T>
+class Base
+{
+public:
+ using Self = Base<T>;
+ using Storage = T;
+
+ constexpr Base(std::initializer_list<int> modes)
+ {
+ for (auto i : modes)
+ m_default_modes |= VTE_MODES_MASK(i);
+ m_modes = m_default_modes;
+ }
+
+ ~Base() = default;
+ Base(Self const&) = default;
+ Base(Self&&) = default;
+ Self& operator= (Self const&) = default;
+ Self& operator= (Self&&) = default;
+
+ inline void set(int bit,
+ bool value) noexcept
+ {
+ vte_modes_set_bool<Storage>(&m_modes, bit, value);
+ }
+
+ constexpr inline bool get(int bit) const noexcept
+ {
+ return vte_modes_get_bool<Storage>(m_modes, bit);
+ }
+
+ inline void set_modes(Storage value) noexcept
+ {
+ m_modes = value;
+ }
+
+ constexpr inline Storage get_modes() const noexcept
+ {
+ return m_modes;
+ }
+
+ void reset() noexcept
+ {
+ set_modes(m_default_modes);
+ }
+
+private:
+ T m_modes{0};
+ T m_default_modes{0};
+};
+
+class ECMA : public Base<uint8_t>
+{
+public:
+ enum Modes {
+ eUNKNOWN = -3,
+ eALWAYS_SET = -2,
+ eALWAYS_RESET = -1,
+
+#define MODE(name,param) e##name,
+#define MODE_FIXED(name,param,value) e##name,
+#include "modes-ecma.hh"
+#undef MODE
+#undef MODE_FIXED
+ };
+
+ int mode_from_param(int param) const noexcept
+ {
+ switch (param) {
+#define MODE(name,param) case param: return e##name;
+#define MODE_FIXED(name,param,value) case param: return e##value;
+#include "modes-ecma.hh"
+#undef MODE
+#undef MODE_FIXED
+ default:
+ return eUNKNOWN;
+ }
+ }
+
+ char const* mode_to_cstring(int param) const noexcept
+ {
+ switch (param) {
+ case eUNKNOWN: return "UNKNOWN";
+ case eALWAYS_SET: return "ALWAYS_SET";
+ case eALWAYS_RESET: return "ALWAYS_RESET";
+#define MODE(name,param) case e##name: return #name;
+#define MODE_FIXED(name,param,value)
+#include "modes-ecma.hh"
+#undef MODE
+#undef MODE_FIXED
+ default:
+ return "INVALID";
+ }
+ }
+
+#define MODE(name,param) MODE_ACCESSOR(name)
+#define MODE_FIXED(name,param,value)
+#include "modes-ecma.hh"
+#undef MODE
+#undef MODE_FIXED
+
+ constexpr ECMA() : Self{eSRM} { }
+
+}; // class ECMA
+
+class Private : public Base<uint32_t>
+{
+public:
+ enum Modes {
+ eUNKNOWN = -3,
+ eALWAYS_SET = -2,
+ eALWAYS_RESET = -1,
+
+#define MODE(name,param) e##name,
+#define MODE_FIXED(name,param,value) e##name,
+#include "modes-private.hh"
+#undef MODE
+#undef MODE_FIXED
+ };
+
+ int mode_from_param(int param) const noexcept
+ {
+ switch (param) {
+#define MODE(name,param) case param: return e##name;
+#define MODE_FIXED(name,param,value) case param: return e##value;
+#include "modes-private.hh"
+#undef MODE
+#undef MODE_FIXED
+ default:
+ return eUNKNOWN;
+ }
+ }
+
+ char const* mode_to_cstring(int param) const noexcept
+ {
+ switch (param) {
+ case eUNKNOWN: return "UNKNOWN";
+ case eALWAYS_SET: return "ALWAYS_SET";
+ case eALWAYS_RESET: return "ALWAYS_RESET";
+#define MODE(name,param) case e##name: return #name;
+#define MODE_FIXED(name,param,value)
+#include "modes-private.hh"
+#undef MODE
+#undef MODE_FIXED
+ default:
+ return "INVALID";
+ }
+ }
+
+#define MODE(name,param) MODE_ACCESSOR(name)
+#define MODE_FIXED(name,param,value)
+#include "modes-private.hh"
+#undef MODE
+#undef MODE_FIXED
+
+ constexpr Private() : Self{eDEC_AUTOWRAP,
+ eDEC_TEXT_CURSOR,
+ eXTERM_ALTBUF_SCROLL,
+ eXTERM_META_SENDS_ESCAPE} { }
+
+ inline void push_saved(int mode)
+ {
+ vte_modes_set_bool<Storage>(&m_saved_modes, mode, get(mode));
+ }
+
+ constexpr inline bool pop_saved(int mode)
+ {
+ return vte_modes_unset_bool<Storage>(&m_saved_modes, mode);
+ }
+
+ inline void clear_saved()
+ {
+ m_saved_modes = 0;
+ }
+
+private:
+ Storage m_saved_modes{0};
+
+}; // class Private
+
+#undef MODE_ACCESSOR
+
+} // namespace modes
+} // namespace terminal
+} // namespace vte
diff --git a/src/vte.cc b/src/vte.cc
index 5864b6d..cf1c55c 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -666,7 +666,7 @@ VteTerminalPrivate::invalidate_cursor_once(bool periodic)
}
}
- if (m_cursor_visible) {
+ if (m_modes_private.DEC_TEXT_CURSOR()) {
auto preedit_width = get_preedit_width(false);
auto row = m_screen->cursor.row;
auto column = m_screen->cursor.col;
@@ -2889,10 +2889,11 @@ VteTerminalPrivate::restore_cursor(VteScreen *screen__)
screen__->cursor.row = screen__->insert_delta + CLAMP(screen__->saved.cursor.row,
0, m_row_count - 1);
- m_reverse_mode = screen__->saved.reverse_mode;
- m_origin_mode = screen__->saved.origin_mode;
- m_sendrecv_mode = screen__->saved.sendrecv_mode;
- m_insert_mode = screen__->saved.insert_mode;
+ m_modes_ecma.set_modes(screen__->saved.modes_ecma);
+
+ m_modes_private.set_DEC_REVERSE_IMAGE(screen__->saved.reverse_mode);
+ m_modes_private.set_DEC_ORIGIN(screen__->saved.origin_mode);
+
m_defaults = screen__->saved.defaults;
m_color_defaults = screen__->saved.color_defaults;
m_fill_defaults = screen__->saved.fill_defaults;
@@ -2908,10 +2909,11 @@ VteTerminalPrivate::save_cursor(VteScreen *screen__)
screen__->saved.cursor.col = screen__->cursor.col;
screen__->saved.cursor.row = screen__->cursor.row - screen__->insert_delta;
- screen__->saved.reverse_mode = m_reverse_mode;
- screen__->saved.origin_mode = m_origin_mode;
- screen__->saved.sendrecv_mode = m_sendrecv_mode;
- screen__->saved.insert_mode = m_insert_mode;
+ screen__->saved.modes_ecma = m_modes_ecma.get_modes();
+
+ screen__->saved.reverse_mode = m_modes_private.DEC_REVERSE_IMAGE();
+ screen__->saved.origin_mode = m_modes_private.DEC_ORIGIN();
+
screen__->saved.defaults = m_defaults;
screen__->saved.color_defaults = m_color_defaults;
screen__->saved.fill_defaults = m_fill_defaults;
@@ -2968,7 +2970,7 @@ VteTerminalPrivate::insert_char(gunichar c,
0x00b7, /* ~ => bullet */
};
- insert |= m_insert_mode;
+ insert |= m_modes_ecma.IRM();
invalidate_now |= insert;
/* If we've enabled the special drawing set, map the characters to
@@ -2987,7 +2989,7 @@ VteTerminalPrivate::insert_char(gunichar c,
/* If we're autowrapping here, do it. */
col = m_screen->cursor.col;
if (G_UNLIKELY (columns && col + columns > m_column_count)) {
- if (m_autowrap) {
+ if (m_modes_private.DEC_AUTOWRAP()) {
_vte_debug_print(VTE_DEBUG_ADJ,
"Autowrapping before character\n");
/* Wrap. */
@@ -3517,7 +3519,7 @@ VteTerminalPrivate::process_incoming()
/* Save the current cursor position. */
saved_cursor = m_screen->cursor;
- saved_cursor_visible = m_cursor_visible;
+ saved_cursor_visible = m_modes_private.DEC_TEXT_CURSOR();
saved_cursor_style = m_cursor_style;
in_scroll_region = m_scrolling_restricted
@@ -3832,7 +3834,7 @@ skip_chunk:
check_cursor_blink();
/* Signal that the cursor moved. */
queue_cursor_moved();
- } else if ((saved_cursor_visible != m_cursor_visible) ||
+ } else if ((saved_cursor_visible != m_modes_private.DEC_TEXT_CURSOR()) ||
(saved_cursor_style != m_cursor_style)) {
invalidate_cell(saved_cursor.col, saved_cursor.row);
check_cursor_blink();
@@ -4122,7 +4124,7 @@ VteTerminalPrivate::pty_io_write(GIOChannel *channel,
void
VteTerminalPrivate::send_child(char const* data,
gssize length,
- bool local_echo)
+ bool local_echo) noexcept
{
gsize icount, ocount;
const guchar *ibuf;
@@ -4265,8 +4267,7 @@ VteTerminalPrivate::feed_child_using_modes(char const* data,
length = strlen(data);
if (length > 0)
- send_child(data, length,
- !m_sendrecv_mode);
+ send_child(data, length, !m_modes_ecma.SRM());
}
/* Send text from the input method to the child. */
@@ -4484,7 +4485,7 @@ VteTerminalPrivate::check_cursor_blink()
{
if (m_has_focus &&
m_cursor_blinks &&
- m_cursor_visible)
+ m_modes_private.DEC_TEXT_CURSOR())
add_cursor_timeout();
else
remove_cursor_timeout();
@@ -4900,8 +4901,8 @@ VteTerminalPrivate::widget_key_press(GdkEventKey *event)
* it to a literal or capability name. */
if (handled == FALSE) {
_vte_keymap_map(keyval, m_modifiers,
- m_cursor_mode == VTE_KEYMODE_APPLICATION,
- m_keypad_mode == VTE_KEYMODE_APPLICATION,
+ m_modes_private.DEC_APPLICATION_CURSOR_KEYS(),
+ m_modes_private.DEC_APPLICATION_KEYPAD(),
&normal,
&normal_length);
/* If we found something this way, suppress
@@ -4958,11 +4959,11 @@ VteTerminalPrivate::widget_key_press(GdkEventKey *event)
if (add_modifiers) {
_vte_keymap_key_add_key_modifiers(keyval,
m_modifiers,
- m_cursor_mode == VTE_KEYMODE_APPLICATION,
+
m_modes_private.DEC_APPLICATION_CURSOR_KEYS(),
&normal,
&normal_length);
}
- if (m_meta_sends_escape &&
+ if (m_modes_private.XTERM_META_SENDS_ESCAPE() &&
!suppress_meta_esc &&
(normal_length > 0) &&
(m_modifiers & VTE_META_MASK)) {
@@ -5245,11 +5246,13 @@ VteTerminalPrivate::widget_paste_received(char const* text)
break;
}
}
- if (m_bracketed_paste_mode)
+
+ bool const bracketed_paste = m_modes_private.XTERM_READLINE_BRACKETED_PASTE();
+ if (bracketed_paste)
feed_child("\e[200~", -1);
// FIXMEchpe add a way to avoid the extra string copy done here
feed_child(paste, p - paste);
- if (m_bracketed_paste_mode)
+ if (bracketed_paste)
feed_child("\e[201~", -1);
g_free(paste);
}
@@ -5296,7 +5299,7 @@ VteTerminalPrivate::feed_mouse_event(vte::grid::coords const& rowcol /* confined
/* With the exception of the 1006 mode, button release is also encoded here. */
/* Note that if multiple extensions are enabled, the 1006 is used, so it's okay to check for only
that. */
- if (is_release && !m_mouse_xterm_extension) {
+ if (is_release && !m_modes_private.XTERM_MOUSE_EXT_SGR()) {
cb = 3;
}
@@ -5317,10 +5320,10 @@ VteTerminalPrivate::feed_mouse_event(vte::grid::coords const& rowcol /* confined
}
/* Check the extensions in decreasing order of preference. Encoding the release event above assumes
that 1006 comes first. */
- if (m_mouse_xterm_extension) {
+ if (m_modes_private.XTERM_MOUSE_EXT_SGR()) {
/* xterm's extended mode (1006) */
len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "<%d;%ld;%ld%c", cb, cx, cy, is_release ? 'm'
: 'M');
- } else if (m_mouse_urxvt_extension) {
+ } else if (m_modes_private.URXVT_MOUSE_EXT()) {
/* urxvt's extended mode (1015) */
len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "%d;%ld;%ldM", 32 + cb, cx, cy);
} else if (cx <= 231 && cy <= 231) {
@@ -5356,7 +5359,7 @@ VteTerminalPrivate::feed_focus_event_initial()
void
VteTerminalPrivate::maybe_feed_focus_event(bool in)
{
- if (m_focus_tracking_mode)
+ if (m_modes_private.XTERM_FOCUS())
feed_focus_event(in);
}
@@ -8021,11 +8024,6 @@ VteTerminalPrivate::VteTerminalPrivate(VteTerminal *t) :
m_last_graphic_character = 0;
/* Set up the emulation. */
- m_keypad_mode = VTE_KEYMODE_NORMAL;
- m_cursor_mode = VTE_KEYMODE_NORMAL;
- m_autowrap = TRUE;
- m_sendrecv_mode = TRUE;
- m_dec_saved = g_hash_table_new(NULL, NULL);
if (vte_parser_new(&m_parser) != 0)
g_assert_not_reached();
@@ -8040,7 +8038,6 @@ VteTerminalPrivate::VteTerminalPrivate(VteTerminal *t) :
/* Scrolling options. */
m_scroll_on_keystroke = TRUE;
- m_alternate_screen_scroll = TRUE;
m_scrollback_lines = -1; /* force update in vte_terminal_set_scrollback_lines */
set_scrollback_lines(VTE_SCROLLBACK_INIT);
@@ -8054,12 +8051,10 @@ VteTerminalPrivate::VteTerminalPrivate(VteTerminal *t) :
/* Miscellaneous options. */
set_backspace_binding(VTE_ERASE_AUTO);
set_delete_binding(VTE_ERASE_AUTO);
- m_meta_sends_escape = TRUE;
m_audible_bell = TRUE;
m_text_blink_mode = VTE_TEXT_BLINK_ALWAYS;
m_allow_bold = TRUE;
m_bold_is_bright = TRUE;
- m_deccolm_mode = FALSE;
m_rewrap_on_resize = TRUE;
set_default_tabstops();
@@ -8070,7 +8065,6 @@ VteTerminalPrivate::VteTerminalPrivate(VteTerminal *t) :
m_cursor_aspect_ratio = 0.04;
/* Cursor blinking. */
- m_cursor_visible = TRUE;
m_cursor_blink_timeout = 500;
m_cursor_blinks = FALSE;
m_cursor_blink_mode = VTE_CURSOR_BLINK_SYSTEM;
@@ -8536,11 +8530,6 @@ VteTerminalPrivate::~VteTerminalPrivate()
g_object_unref(m_pty);
}
- /* Remove hash tables. */
- if (m_dec_saved != NULL) {
- g_hash_table_destroy(m_dec_saved);
- }
-
/* Clean up emulation structures. */
m_parser = vte_parser_free(m_parser);
g_assert_null(m_parser);
@@ -8705,7 +8694,7 @@ VteTerminalPrivate::determine_colors(VteCellAttr const* attr,
vte_color_triple_get(attr->colors(), &fore, &back, &deco);
/* Reverse-mode switches default fore and back colors */
- if (G_UNLIKELY (m_reverse_mode)) {
+ if (G_UNLIKELY (m_modes_private.DEC_REVERSE_IMAGE())) {
if (fore == VTE_DEFAULT_FG)
fore = VTE_DEFAULT_BG;
if (back == VTE_DEFAULT_BG)
@@ -9656,12 +9645,19 @@ VteTerminalPrivate::paint_cursor()
int x, y;
gboolean blink, selected, focus;
- if (!m_cursor_visible)
+ //FIXMEchpe this should already be reflected in the m_cursor_blink_state below
+ if (!m_modes_private.DEC_TEXT_CURSOR())
return;
if (m_im_preedit_active)
return;
+ focus = m_has_focus;
+ blink = m_cursor_blink_state;
+
+ if (focus && !blink)
+ return;
+
col = m_screen->cursor.col;
drow = m_screen->cursor.row;
width = m_cell_width;
@@ -9671,12 +9667,6 @@ VteTerminalPrivate::paint_cursor()
if (CLAMP(col, 0, m_column_count - 1) != col)
return;
- focus = m_has_focus;
- blink = m_cursor_blink_state;
-
- if (focus && !blink)
- return;
-
/* Find the first cell of the character "under" the cursor.
* This is for CJK. For TAB, paint the cursor where it really is. */
auto cell = find_charcell(col, drow);
@@ -10107,7 +10097,7 @@ VteTerminalPrivate::widget_scroll(GdkEventScroll *event)
"Scroll speed is %d lines per non-smooth scroll unit\n",
(int) v);
if (m_screen == &m_alternate_screen &&
- m_alternate_screen_scroll) {
+ m_modes_private.XTERM_ALTBUF_SCROLL()) {
char *normal;
gssize normal_length;
@@ -10125,8 +10115,8 @@ VteTerminalPrivate::widget_scroll(GdkEventScroll *event)
_vte_keymap_map (
cnt > 0 ? GDK_KEY_Down : GDK_KEY_Up,
m_modifiers,
- m_cursor_mode == VTE_KEYMODE_APPLICATION,
- m_keypad_mode == VTE_KEYMODE_APPLICATION,
+ m_modes_private.DEC_APPLICATION_CURSOR_KEYS(),
+ m_modes_private.DEC_APPLICATION_KEYPAD(),
&normal,
&normal_length);
if (cnt < 0)
@@ -10491,20 +10481,13 @@ VteTerminalPrivate::reset(bool clear_tabstops,
vte_parser_reset(m_parser);
m_last_graphic_character = 0;
- /* Reset keypad/cursor key modes. */
- m_keypad_mode = VTE_KEYMODE_NORMAL;
- m_cursor_mode = VTE_KEYMODE_NORMAL;
- /* Enable autowrap. */
- m_autowrap = TRUE;
- /* Enable meta-sends-escape. */
- m_meta_sends_escape = TRUE;
- /* Disable DECCOLM mode. */
- m_deccolm_mode = FALSE;
- /* Reset saved settings. */
- if (m_dec_saved != NULL) {
- g_hash_table_destroy(m_dec_saved);
- m_dec_saved = g_hash_table_new(NULL, NULL);
- }
+ /* Reset modes */
+ m_modes_ecma.reset();
+ m_modes_private.clear_saved();
+ m_modes_private.reset();
+
+ update_mouse_protocol();
+
/* Reset the color palette. Only the 256 indexed colors, not the special ones, as per xterm. */
for (int i = 0; i < 256; i++)
m_palette[i].sources[VTE_COLOR_SOURCE_ESCAPE].is_set = FALSE;
@@ -10542,13 +10525,6 @@ VteTerminalPrivate::reset(bool clear_tabstops,
/* Reset restricted scrolling regions, leave insert mode, make
* the cursor visible again. */
m_scrolling_restricted = FALSE;
- m_sendrecv_mode = TRUE;
- m_insert_mode = FALSE;
- m_origin_mode = FALSE;
- m_reverse_mode = FALSE;
- m_cursor_visible = TRUE;
- /* For some reason, xterm doesn't reset alternateScroll, but we do. */
- m_alternate_screen_scroll = TRUE;
/* Reset the visual bits of selection on hard reset, see bug 789954. */
if (clear_history) {
deselect_all();
@@ -10567,19 +10543,12 @@ VteTerminalPrivate::reset(bool clear_tabstops,
}
/* Reset mouse motion events. */
- m_mouse_tracking_mode = MOUSE_TRACKING_NONE;
- apply_mouse_cursor();
m_mouse_pressed_buttons = 0;
m_mouse_handled_buttons = 0;
- m_mouse_xterm_extension = FALSE;
- m_mouse_urxvt_extension = FALSE;
+ m_mouse_last_position = vte::view::coords(-1, -1);
m_mouse_smooth_scroll_delta = 0.;
- /* Reset focus tracking */
- m_focus_tracking_mode = FALSE;
/* Clear modifiers. */
m_modifiers = 0;
- /* Reset miscellaneous stuff. */
- m_bracketed_paste_mode = FALSE;
/* Reset the saved cursor. */
save_cursor(&m_normal_screen);
save_cursor(&m_alternate_screen);
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index d8bcd4e..bf38fbd 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -28,6 +28,7 @@
#include "buffer.h"
#include "parser.hh"
#include "parser-glue.hh"
+#include "modes.hh"
#include "vtepcre2.h"
#include "vteregexinternal.hh"
@@ -71,13 +72,6 @@ typedef enum _VteCharacterReplacement {
VTE_CHARACTER_REPLACEMENT_BRITISH
} VteCharacterReplacement;
-/* The terminal's keypad/cursor state. A terminal can either be using the
- * normal keypad, or the "application" keypad. */
-typedef enum _VteKeymode {
- VTE_KEYMODE_NORMAL,
- VTE_KEYMODE_APPLICATION
-} VteKeymode;
-
typedef struct _VtePaletteColor {
struct {
vte::color::rgb color;
@@ -126,10 +120,9 @@ struct _VteScreen {
/* Stuff saved along with the cursor */
struct {
VteVisualPosition cursor; /* onscreen coordinate, that is, relative to insert_delta */
- gboolean reverse_mode;
- gboolean origin_mode;
- gboolean sendrecv_mode;
- gboolean insert_mode;
+ uint8_t modes_ecma;
+ bool reverse_mode;
+ bool origin_mode;
VteCell defaults;
VteCell color_defaults;
VteCell fill_defaults;
@@ -277,10 +270,8 @@ public:
/* Emulation setup data. */
struct vte_parser* m_parser; /* control sequence state machine */
- gboolean m_autowrap; /* auto wraparound at right margin */
- int m_keypad_mode, m_cursor_mode; /* these would be VteKeymodes, but we
- need to guarantee its type */
- GHashTable *m_dec_saved;
+ vte::terminal::modes::ECMA m_modes_ecma{};
+ vte::terminal::modes::Private m_modes_private{};
/* PTY handling data. */
VtePty *m_pty;
@@ -322,11 +313,6 @@ public:
* screen, which seems to be a DEC-specific feature. */
struct _VteScreen m_normal_screen, m_alternate_screen, *m_screen;
- /* Values we save along with the cursor */
- gboolean m_reverse_mode; /* reverse mode */
- gboolean m_origin_mode; /* origin mode */
- gboolean m_sendrecv_mode; /* sendrecv mode */
- gboolean m_insert_mode; /* insert mode */
VteCell m_defaults; /* default characteristics
for insertion of any new
characters */
@@ -369,22 +355,18 @@ public:
/* Miscellaneous options. */
VteEraseBinding m_backspace_binding;
VteEraseBinding m_delete_binding;
- gboolean m_meta_sends_escape;
gboolean m_audible_bell;
gboolean m_allow_bold;
gboolean m_bold_is_bright;
- gboolean m_deccolm_mode; /* DECCOLM allowed */
GHashTable *m_tabstops;
gboolean m_text_modified_flag;
gboolean m_text_inserted_flag;
gboolean m_text_deleted_flag;
gboolean m_rewrap_on_resize;
- gboolean m_bracketed_paste_mode;
/* Scrolling options. */
gboolean m_scroll_on_output;
gboolean m_scroll_on_keystroke;
- gboolean m_alternate_screen_scroll;
vte::grid::row_t m_scrollback_lines;
/* Restricted scrolling */
@@ -403,7 +385,6 @@ public:
gint m_cursor_blink_timeout; /* gtk-cursor-blink-timeout */
gboolean m_cursor_blinks; /* whether the cursor is actually blinking */
gint64 m_cursor_blink_time; /* how long the cursor has been blinking yet */
- gboolean m_cursor_visible;
gboolean m_has_focus; /* is the terminal window focused */
/* Contents blinking */
@@ -421,8 +402,7 @@ public:
gboolean m_input_enabled;
time_t m_last_keypress_time;
- int m_mouse_tracking_mode; /* this is of type MouseTrackingMode,
- but we need to guarantee its type. */
+ MouseTrackingMode m_mouse_tracking_mode{MOUSE_TRACKING_NONE};
guint m_mouse_pressed_buttons; /* bits 0, 1, 2 resp. for buttons 1, 2, 3 */
guint m_mouse_handled_buttons; /* similar bitmap for buttons we handled ourselves */
/* The last known position the mouse pointer from an event. We don't store
@@ -431,11 +411,7 @@ public:
*/
vte::view::coords m_mouse_last_position;
guint m_mouse_autoscroll_tag;
- gboolean m_mouse_xterm_extension;
- gboolean m_mouse_urxvt_extension;
- double m_mouse_smooth_scroll_delta;
-
- gboolean m_focus_tracking_mode;
+ double m_mouse_smooth_scroll_delta{0.0};
/* State variables for handling match checks. */
char* m_match_contents;
@@ -790,7 +766,7 @@ public:
void feed_chunks(struct _vte_incoming_chunk *chunks);
void send_child(char const* data,
gssize length,
- bool local_echo);
+ bool local_echo) noexcept;
void feed_child_using_modes(char const* data,
gssize length);
@@ -1171,23 +1147,20 @@ public:
inline void switch_alternate_screen();
inline void save_cursor();
inline void restore_cursor();
- inline void switch_normal_screen_and_restore_cursor();
- inline void save_cursor_and_switch_alternate_screen();
void set_title_internal(vte::parser::Params const& params,
bool icon_title,
bool window_title);
- inline void set_mode(vte::parser::Params const& params,
- bool value);
- inline void reset_mouse_smooth_scroll_delta();
- inline void enter_focus_tracking_mode();
- inline void decset(long setting,
- bool restore,
- bool save,
- bool set);
- inline void decset(vte::parser::Params const& params,
- bool restore,
- bool save,
- bool set);
+
+ inline void set_mode_ecma(vte::parser::Sequence const& seq,
+ bool set) noexcept;
+ inline void set_mode_private(vte::parser::Sequence const& seq,
+ bool set) noexcept;
+ inline void set_mode_private(int mode,
+ bool set) noexcept;
+ inline void save_mode_private(vte::parser::Sequence const& seq,
+ bool save) noexcept;
+ void update_mouse_protocol() noexcept;
+
inline void set_character_replacements(unsigned slot,
VteCharacterReplacement replacement);
inline void set_character_replacement(unsigned slot);
@@ -1222,7 +1195,6 @@ public:
char const* terminator);
inline void line_feed();
inline void set_current_hyperlink(char* hyperlink_params /* adopted */, char* uri /* adopted */);
- inline void set_keypad_mode(VteKeymode mode);
inline void erase_in_display(vte::parser::Sequence const& seq);
inline void erase_in_line(vte::parser::Sequence const& seq);
inline void insert_lines(vte::grid::row_t param);
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 2c9238c..692f560 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -410,22 +410,6 @@ VteTerminalPrivate::switch_alternate_screen()
switch_screen(&m_alternate_screen);
}
-/* Switch to normal screen and restore cursor (in this order). */
-void
-VteTerminalPrivate::switch_normal_screen_and_restore_cursor()
-{
- switch_normal_screen();
- restore_cursor();
-}
-
-/* Save cursor and switch to alternate screen (in this order). */
-void
-VteTerminalPrivate::save_cursor_and_switch_alternate_screen()
-{
- save_cursor();
- switch_alternate_screen();
-}
-
/* Set icon/window titles. */
void
VteTerminalPrivate::set_title_internal(vte::parser::Params const& params,
@@ -471,398 +455,209 @@ VteTerminalPrivate::set_title_internal(vte::parser::Params const& params,
g_free(title);
}
-/* Toggle a terminal mode. */
void
-VteTerminalPrivate::set_mode(vte::parser::Sequence const& params,
- bool value)
+VteTerminalPrivate::set_mode_ecma(vte::parser::Sequence const& seq,
+ bool set) noexcept
{
- auto n_params = params.size();
- if (n_params == 0)
- return;
+ auto const n_params = seq.size();
+ for (unsigned int i = 0; i < n_params; i = seq.next(i)) {
+ auto const param = seq.collect1(i);
+ auto const mode = m_modes_ecma.mode_from_param(param);
+
+ _vte_debug_print(VTE_DEBUG_MODES,
+ "Mode %d (%s) %s\n",
+ param, m_modes_ecma.mode_to_cstring(mode),
+ set ? "set" : "reset");
- for (unsigned int i = 0; i < n_params; i++) {
- int setting;
- if (!params.number_at_unchecked(i, setting))
+ if (mode < 0)
continue;
- switch (setting) {
- case 2: /* keyboard action mode (?) */
- break;
- case 4: /* insert/overtype mode */
- m_insert_mode = value;
- break;
- case 12: /* send/receive mode (local echo) */
- m_sendrecv_mode = value;
- break;
- default:
- break;
- }
+ m_modes_ecma.set(mode, set);
}
}
void
-VteTerminalPrivate::reset_mouse_smooth_scroll_delta()
+VteTerminalPrivate::update_mouse_protocol() noexcept
{
- m_mouse_smooth_scroll_delta = 0.0;
-}
+ if (m_modes_private.XTERM_MOUSE_ANY_EVENT())
+ m_mouse_tracking_mode = MOUSE_TRACKING_ALL_MOTION_TRACKING;
+ else if (m_modes_private.XTERM_MOUSE_BUTTON_EVENT())
+ m_mouse_tracking_mode = MOUSE_TRACKING_CELL_MOTION_TRACKING;
+ else if (m_modes_private.XTERM_MOUSE_VT220_HIGHLIGHT())
+ m_mouse_tracking_mode = MOUSE_TRACKING_HILITE_TRACKING;
+ else if (m_modes_private.XTERM_MOUSE_VT220())
+ m_mouse_tracking_mode = MOUSE_TRACKING_SEND_XY_ON_BUTTON;
+ else if (m_modes_private.XTERM_MOUSE_X10())
+ m_mouse_tracking_mode = MOUSE_TRACKING_SEND_XY_ON_CLICK;
+ else
+ m_mouse_tracking_mode = MOUSE_TRACKING_NONE;
+
+ m_mouse_smooth_scroll_delta = 0.0;
-typedef void (VteTerminalPrivate::* decset_handler_t)();
+ /* Mouse pointer might change */
+ apply_mouse_cursor();
-struct decset_t {
- gint16 setting;
- /* offset in VteTerminalPrivate (> 0) or VteScreen (< 0) */
- gint16 boffset;
- gint16 ioffset;
- gint16 poffset;
- gint16 fvalue;
- gint16 tvalue;
- decset_handler_t reset, set;
-};
+ _vte_debug_print(VTE_DEBUG_MODES,
+ "Mouse protocol is now %d\n", m_mouse_tracking_mode);
+}
-static int
-decset_cmp(const void *va,
- const void *vb)
+void
+VteTerminalPrivate::set_mode_private(int mode,
+ bool set) noexcept
{
- const struct decset_t *a = (const struct decset_t *)va;
- const struct decset_t *b = (const struct decset_t *)vb;
+ /* Pre actions */
+ switch (mode) {
+ default:
+ break;
+ }
+
+ m_modes_private.set(mode, set);
+
+ /* Post actions */
+ switch (mode) {
+ case vte::terminal::modes::Private::eDEC_132_COLUMN:
+ /* DECCOLM: set/reset to 132/80 columns mode, clear screen and cursor home */
+ // FIXMEchpe don't do clear screen if DECNCSM is set
+ if (m_modes_private.XTERM_DECCOLM()) {
+ emit_resize_window(set ? 132 : 80, m_row_count);
+ clear_screen();
+ home_cursor();
+ }
+ break;
+
+ case vte::terminal::modes::Private::eDEC_REVERSE_IMAGE:
+ invalidate_all();
+ break;
+
+ case vte::terminal::modes::Private::eDEC_ORIGIN:
+ /* Reposition the cursor in its new home position. */
+ home_cursor();
+ break;
+
+ case vte::terminal::modes::Private::eDEC_TEXT_CURSOR:
+ /* No need to invalidate the cursor here, this is done
+ * in process_incoming().
+ */
+ break;
+
+ case vte::terminal::modes::Private::eXTERM_ALTBUF:
+ /* [[fallthrough]]; */
+ case vte::terminal::modes::Private::eXTERM_OPT_ALTBUF:
+ /* [[fallthrough]]; */
+ case vte::terminal::modes::Private::eXTERM_OPT_ALTBUF_SAVE_CURSOR:
+ if (set) {
+ if (mode == vte::terminal::modes::Private::eXTERM_OPT_ALTBUF_SAVE_CURSOR)
+ save_cursor();
+
+ switch_alternate_screen();
+
+ /* Clear the alternate screen */
+ if (mode == vte::terminal::modes::Private::eXTERM_OPT_ALTBUF_SAVE_CURSOR)
+ clear_screen();
+ } else {
+ if (mode == vte::terminal::modes::Private::eXTERM_OPT_ALTBUF &&
+ m_screen == &m_alternate_screen)
+ clear_screen();
+
+ switch_normal_screen();
- return a->setting < b->setting ? -1 : a->setting > b->setting;
+ if (mode == vte::terminal::modes::Private::eXTERM_OPT_ALTBUF_SAVE_CURSOR)
+ restore_cursor();
+ }
+
+ /* Reset scrollbars and repaint everything. */
+ gtk_adjustment_set_value(m_vadjustment,
+ m_screen->scroll_delta);
+ set_scrollback_lines(m_scrollback_lines);
+ queue_contents_changed();
+ invalidate_all();
+ break;
+
+ case vte::terminal::modes::Private::eXTERM_SAVE_CURSOR:
+ if (set)
+ save_cursor();
+ else
+ restore_cursor();
+ break;
+
+ case vte::terminal::modes::Private::eXTERM_MOUSE_X10:
+ case vte::terminal::modes::Private::eXTERM_MOUSE_VT220:
+ case vte::terminal::modes::Private::eXTERM_MOUSE_VT220_HIGHLIGHT:
+ case vte::terminal::modes::Private::eXTERM_MOUSE_BUTTON_EVENT:
+ case vte::terminal::modes::Private::eXTERM_MOUSE_ANY_EVENT:
+ case vte::terminal::modes::Private::eXTERM_MOUSE_EXT:
+ case vte::terminal::modes::Private::eXTERM_MOUSE_EXT_SGR:
+ case vte::terminal::modes::Private::eURXVT_MOUSE_EXT:
+ update_mouse_protocol();
+ break;
+
+ case vte::terminal::modes::Private::eXTERM_FOCUS:
+ if (set)
+ feed_focus_event_initial();
+ break;
+
+ default:
+ break;
+ }
}
-/* Manipulate certain terminal attributes. */
void
-VteTerminalPrivate::decset(vte::parser::Sequence const& params,
- bool restore,
- bool save,
- bool set)
+VteTerminalPrivate::set_mode_private(vte::parser::Sequence const& seq,
+ bool set) noexcept
{
+ auto const n_params = seq.size();
+ for (unsigned int i = 0; i < n_params; i = seq.next(i)) {
+ auto const param = seq.collect1(i);
+ auto const mode = m_modes_private.mode_from_param(param);
- auto n_params = params.size();
- for (unsigned int i = 0; i < n_params; i++) {
- int setting;
+ _vte_debug_print(VTE_DEBUG_MODES,
+ "Private mode %d (%s) %s\n",
+ param, m_modes_private.mode_to_cstring(mode),
+ set ? "set" : "reset");
- if (!params.number_at(i, setting))
+ if (mode < 0)
continue;
- decset(setting, restore, save, set);
- }
+ set_mode_private(mode, set);
+ }
}
void
-VteTerminalPrivate::decset(long setting,
- bool restore,
- bool save,
- bool set)
-{
- static const struct decset_t settings[] = {
-#define PRIV_OFFSET(member) (G_STRUCT_OFFSET(VteTerminalPrivate, member))
-#define SCREEN_OFFSET(member) (-G_STRUCT_OFFSET(VteScreen, member))
- /* 1: Application/normal cursor keys. */
- {1, 0, PRIV_OFFSET(m_cursor_mode), 0,
- VTE_KEYMODE_NORMAL,
- VTE_KEYMODE_APPLICATION,
- nullptr, nullptr,},
- /* 2: disallowed, we don't do VT52. */
- {2, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 3: DECCOLM set/reset to and from 132/80 columns */
- {3, 0, 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 5: Reverse video. */
- {5, PRIV_OFFSET(m_reverse_mode), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 6: Origin mode: when enabled, cursor positioning is
- * relative to the scrolling region. */
- {6, PRIV_OFFSET(m_origin_mode), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 7: Wraparound mode. */
- {7, PRIV_OFFSET(m_autowrap), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 8: disallowed, keyboard repeat is set by user. */
- {8, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 9: Send-coords-on-click. */
- {9, 0, PRIV_OFFSET(m_mouse_tracking_mode), 0,
- 0,
- MOUSE_TRACKING_SEND_XY_ON_CLICK,
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,},
- /* 12: disallowed, cursor blinks is set by user. */
- {12, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 18: print form feed. */
- /* 19: set print extent to full screen. */
- /* 25: Cursor visible. */
- {25, PRIV_OFFSET(m_cursor_visible), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 30/rxvt: disallowed, scrollbar visibility is set by user. */
- {30, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 35/rxvt: disallowed, fonts set by user. */
- {35, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 38: enter Tektronix mode. */
- /* 40: Enable DECCOLM mode. */
- {40, PRIV_OFFSET(m_deccolm_mode), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 41: more(1) fix. */
- /* 42: Enable NLS replacements. */
- /* 44: Margin bell. */
- /* 47: Alternate screen. */
- {47, 0, 0, 0,
- 0,
- 0,
- &VteTerminalPrivate::switch_normal_screen,
- &VteTerminalPrivate::switch_alternate_screen,},
- /* 66: Keypad mode. */
- {66, PRIV_OFFSET(m_keypad_mode), 0, 0,
- VTE_KEYMODE_NORMAL,
- VTE_KEYMODE_APPLICATION,
- nullptr, nullptr,},
- /* 67: disallowed, backspace key policy is set by user. */
- {67, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 1000: Send-coords-on-button. */
- {1000, 0, PRIV_OFFSET(m_mouse_tracking_mode), 0,
- 0,
- MOUSE_TRACKING_SEND_XY_ON_BUTTON,
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,},
- /* 1001: Hilite tracking. */
- {1001, 0, PRIV_OFFSET(m_mouse_tracking_mode), 0,
- (0),
- (MOUSE_TRACKING_HILITE_TRACKING),
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,},
- /* 1002: Cell motion tracking. */
- {1002, 0, PRIV_OFFSET(m_mouse_tracking_mode), 0,
- (0),
- (MOUSE_TRACKING_CELL_MOTION_TRACKING),
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,},
- /* 1003: All motion tracking. */
- {1003, 0, PRIV_OFFSET(m_mouse_tracking_mode), 0,
- (0),
- (MOUSE_TRACKING_ALL_MOTION_TRACKING),
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,
- &VteTerminalPrivate::reset_mouse_smooth_scroll_delta,},
- /* 1004: Focus tracking. */
- {1004, PRIV_OFFSET(m_focus_tracking_mode), 0, 0,
- FALSE,
- TRUE,
- nullptr,
- &VteTerminalPrivate::feed_focus_event_initial,},
- /* 1006: Extended mouse coordinates. */
- {1006, PRIV_OFFSET(m_mouse_xterm_extension), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 1007: Alternate screen scroll. */
- {1007, PRIV_OFFSET(m_alternate_screen_scroll), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 1010/rxvt: disallowed, scroll-on-output is set by user. */
- {1010, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 1011/rxvt: disallowed, scroll-on-keypress is set by user. */
- {1011, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 1015/urxvt: Extended mouse coordinates. */
- {1015, PRIV_OFFSET(m_mouse_urxvt_extension), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 1035: disallowed, don't know what to do with it. */
- {1035, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 1036: Meta-sends-escape. */
- {1036, PRIV_OFFSET(m_meta_sends_escape), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
- /* 1037: disallowed, delete key policy is set by user. */
- {1037, 0, 0, 0, 0, 0, nullptr, nullptr,},
- /* 1047: Use alternate screen buffer. */
- {1047, 0, 0, 0,
- 0,
- 0,
- &VteTerminalPrivate::switch_normal_screen,
- &VteTerminalPrivate::switch_alternate_screen,},
- /* 1048: Save/restore cursor position. */
- {1048, 0, 0, 0,
- 0,
- 0,
- &VteTerminalPrivate::restore_cursor,
- &VteTerminalPrivate::save_cursor,},
- /* 1049: Use alternate screen buffer, saving the cursor
- * position. */
- {1049, 0, 0, 0,
- 0,
- 0,
- &VteTerminalPrivate::switch_normal_screen_and_restore_cursor,
- &VteTerminalPrivate::save_cursor_and_switch_alternate_screen,},
- /* 2004: Bracketed paste mode. */
- {2004, PRIV_OFFSET(m_bracketed_paste_mode), 0, 0,
- FALSE,
- TRUE,
- nullptr, nullptr,},
-#undef PRIV_OFFSET
-#undef SCREEN_OFFSET
- };
- struct decset_t key;
- struct decset_t *found;
-
- /* Handle the setting. */
- key.setting = setting;
- found = (struct decset_t *)bsearch(&key, settings, G_N_ELEMENTS(settings), sizeof(settings[0]),
decset_cmp);
- if (!found) {
- _vte_debug_print (VTE_DEBUG_MISC,
- "DECSET/DECRESET mode %ld not recognized, ignoring.\n",
- setting);
- return;
- }
-
- key = *found;
- do {
- gboolean *bvalue = NULL;
- gint *ivalue = NULL;
- gpointer *pvalue = NULL, pfvalue = NULL, ptvalue = NULL;
- gpointer p;
-
- /* Handle settings we want to ignore. */
- if ((key.fvalue == key.tvalue) &&
- (!key.set) &&
- (!key.reset)) {
- break;
- }
+VteTerminalPrivate::save_mode_private(vte::parser::Sequence const& seq,
+ bool save) noexcept
+{
+ auto const n_params = seq.size();
+ for (unsigned int i = 0; i < n_params; i = seq.next(i)) {
+ auto const param = seq.collect1(i);
+ auto const mode = m_modes_private.mode_from_param(param);
-#define STRUCT_MEMBER_P(type,total_offset) \
- (type) (total_offset >= 0 ? G_STRUCT_MEMBER_P(this, total_offset) :
G_STRUCT_MEMBER_P(m_screen, -total_offset))
-
- if (key.boffset) {
- bvalue = STRUCT_MEMBER_P(gboolean*, key.boffset);
- } else if (key.ioffset) {
- ivalue = STRUCT_MEMBER_P(int*, key.ioffset);
- } else if (key.poffset) {
- pvalue = STRUCT_MEMBER_P(gpointer*, key.poffset);
- pfvalue = STRUCT_MEMBER_P(gpointer, key.fvalue);
- ptvalue = STRUCT_MEMBER_P(gpointer, key.tvalue);
+ if (mode < 0) {
+ _vte_debug_print(VTE_DEBUG_MODES,
+ "Saving private mode %d (%s)\n",
+ param, m_modes_private.mode_to_cstring(mode));
+ continue;
}
-#undef STRUCT_MEMBER_P
-
- /* Read the old setting. */
- if (restore) {
- p = g_hash_table_lookup(m_dec_saved,
- GINT_TO_POINTER(setting));
- set = (p != NULL);
- _vte_debug_print(VTE_DEBUG_PARSER,
- "Setting %ld was %s.\n",
- setting, set ? "set" : "unset");
- }
- /* Save the current setting. */
- if (save) {
- if (bvalue) {
- set = *(bvalue) != FALSE;
- } else
- if (ivalue) {
- set = *(ivalue) == (int)key.tvalue;
- } else
- if (pvalue) {
- set = *(pvalue) == ptvalue;
- }
- _vte_debug_print(VTE_DEBUG_PARSER,
- "Setting %ld is %s, saving.\n",
- setting, set ? "set" : "unset");
- g_hash_table_insert(m_dec_saved,
- GINT_TO_POINTER(setting),
- GINT_TO_POINTER(set));
- }
- /* Change the current setting to match the new/saved value. */
- if (!save) {
- _vte_debug_print(VTE_DEBUG_PARSER,
- "Setting %ld to %s.\n",
- setting, set ? "set" : "unset");
- if (key.set && set) {
- (this->*key.set)();
- }
- if (bvalue) {
- *(bvalue) = set;
- } else
- if (ivalue) {
- *(ivalue) = set ? (int)key.tvalue : (int)key.fvalue;
- } else
- if (pvalue) {
- *(pvalue) = set ? ptvalue : pfvalue;
- }
- if (key.reset && !set) {
- (this->*key.reset)();
- }
- }
- } while (0);
- /* Do whatever's necessary when the setting changes. */
- switch (setting) {
- case 1:
- _vte_debug_print(VTE_DEBUG_KEYBOARD, set ?
- "Entering application cursor mode.\n" :
- "Leaving application cursor mode.\n");
- break;
- case 3:
- /* 3: DECCOLM set/reset to 132/80 columns mode, clear screen and cursor home */
- if (m_deccolm_mode) {
- emit_resize_window(set ? 132 : 80,
- m_row_count);
- clear_screen();
- home_cursor();
+ if (save) {
+ _vte_debug_print(VTE_DEBUG_MODES,
+ "Saving private mode %d (%s) is %s\n",
+ param, m_modes_private.mode_to_cstring(mode),
+ m_modes_private.get(mode) ? "set" : "reset");
+
+ m_modes_private.push_saved(mode);
+ } else {
+ bool const set = m_modes_private.pop_saved(mode);
+
+ _vte_debug_print(VTE_DEBUG_MODES,
+ "Restoring private mode %d (%s) to %s\n",
+ param, m_modes_private.mode_to_cstring(mode),
+ set ? "set" : "reset");
+
+ set_mode_private(mode, set);
}
- break;
- case 5:
- /* Repaint everything in reverse mode. */
- invalidate_all();
- break;
- case 6:
- /* Reposition the cursor in its new home position. */
- home_cursor();
- break;
- case 47:
- case 1047:
- case 1049:
- /* Clear the alternate screen if we're switching to it */
- if (set) {
- clear_screen();
- }
- /* Reset scrollbars and repaint everything. */
- gtk_adjustment_set_value(m_vadjustment,
- m_screen->scroll_delta);
- set_scrollback_lines(m_scrollback_lines);
- queue_contents_changed();
- invalidate_all();
- break;
- case 9:
- case 1000:
- case 1001:
- case 1002:
- case 1003:
- /* Mouse pointer might change. */
- apply_mouse_cursor();
- break;
- case 66:
- _vte_debug_print(VTE_DEBUG_KEYBOARD, set ?
- "Entering application keypad mode.\n" :
- "Leaving application keypad mode.\n");
- break;
- default:
- break;
- }
+ }
}
-/* THE HANDLERS */
-
-/* Do nothing. */
void
VteTerminalPrivate::set_character_replacement(unsigned slot)
{
@@ -1024,7 +819,7 @@ void
VteTerminalPrivate::set_cursor_row(vte::grid::row_t row)
{
vte::grid::row_t start_row, end_row;
- if (m_origin_mode &&
+ if (m_modes_private.DEC_ORIGIN() &&
m_scrolling_restricted) {
start_row = m_scrolling_region.start;
end_row = m_scrolling_region.end;
@@ -1054,7 +849,7 @@ vte::grid::row_t
VteTerminalPrivate::get_cursor_row() const
{
auto row = m_screen->cursor.row - m_screen->insert_delta;
- /* Note that we do NOT check m_origin_mode here! */
+ /* Note that we do NOT check DEC_ORIGIN mode here! */
if (m_scrolling_restricted) {
row -= m_scrolling_region.start;
}
@@ -1140,7 +935,7 @@ VteTerminalPrivate::move_cursor_down(vte::grid::row_t rows)
ensure_cursor_is_onscreen();
vte::grid::row_t end;
- // FIXMEchpe why not check m_origin_mode here?
+ // FIXMEchpe why not check DEC_ORIGIN here?
if (m_scrolling_restricted) {
end = m_screen->insert_delta + m_scrolling_region.end;
} else {
@@ -1398,7 +1193,7 @@ VteTerminalPrivate::move_cursor_up(vte::grid::row_t rows)
ensure_cursor_is_onscreen();
vte::grid::row_t start;
- //FIXMEchpe why not check m_origin_mode here?
+ //FIXMEchpe why not check DEC_ORIGIN mode here?
if (m_scrolling_restricted) {
start = m_screen->insert_delta + m_scrolling_region.start;
} else {
@@ -1666,12 +1461,6 @@ VteTerminalPrivate::set_current_hyperlink(char *hyperlink_params /* adopted */,
}
void
-VteTerminalPrivate::set_keypad_mode(VteKeymode mode)
-{
- m_keypad_mode = mode;
-}
-
-void
VteTerminalPrivate::erase_in_display(vte::parser::Sequence const& seq)
{
/* We don't implement the protected attribute, so we can ignore selective:
@@ -2946,11 +2735,8 @@ VteTerminalPrivate::DECKPAM(vte::parser::Sequence const& seq)
* top-row or on the keypad.
* Default is keypad-numeric-mode.
*/
-#if 0
- screen->flags |= VTE_FLAG_KEYPAD_MODE;
-#endif
- set_keypad_mode(VTE_KEYMODE_APPLICATION);
+ set_mode_private(vte::terminal::modes::Private::eDEC_APPLICATION_KEYPAD, true);
}
void
@@ -2963,11 +2749,7 @@ VteTerminalPrivate::DECKPNM(vte::parser::Sequence const& seq)
* sequences as corresponding keypresses on the main keyboard.
* Default is keypad-numeric-mode.
*/
-#if 0
- screen->flags &= ~VTE_FLAG_KEYPAD_MODE;
-#endif
-
- set_keypad_mode(VTE_KEYMODE_NORMAL);
+ set_mode_private(vte::terminal::modes::Private::eDEC_APPLICATION_KEYPAD, false);
}
void
@@ -3948,7 +3730,7 @@ VteTerminalPrivate::DSR_ECMA(vte::parser::Sequence const& seq)
/* Send the cursor position. */
vte::grid::row_t rowval, origin, rowmax;
- if (m_origin_mode &&
+ if (m_modes_private.DEC_ORIGIN() &&
m_scrolling_restricted) {
origin = m_scrolling_region.start;
rowmax = m_scrolling_region.end;
@@ -3991,7 +3773,7 @@ VteTerminalPrivate::DSR_DEC(vte::parser::Sequence const& seq)
case 6:
/* Send the cursor position. */
vte::grid::row_t rowval, origin, rowmax;
- if (m_origin_mode &&
+ if (m_modes_private.DEC_ORIGIN() &&
m_scrolling_restricted) {
origin = m_scrolling_region.start;
rowmax = m_scrolling_region.end;
@@ -4733,14 +4515,8 @@ VteTerminalPrivate::RM_ECMA(vte::parser::Sequence const& seq)
*
* References: ECMA-48 § 8.3.106
*/
-#if 0
- unsigned int i;
-
- for (i = 0; i < seq->n_args; ++i)
- screen_mode_change_ansi(screen, seq->args[i], false);
-#endif
- set_mode(seq, false);
+ set_mode_ecma(seq, false);
}
void
@@ -4754,14 +4530,8 @@ VteTerminalPrivate::RM_DEC(vte::parser::Sequence const& seq)
*
* References: VT525
*/
-#if 0
- unsigned int i;
-
- for (i = 0; i < seq->n_args; ++i)
- screen_mode_change_dec(screen, seq->args[i], false);
-#endif
- decset(seq, false, false, false);
+ set_mode_private(seq, false);
}
void
@@ -4954,14 +4724,8 @@ VteTerminalPrivate::SM_ECMA(vte::parser::Sequence const& seq)
*
* References: ECMA-48 § 8.3.125
*/
-#if 0
- unsigned int i;
-
- for (i = 0; i < seq->n_args; ++i)
- screen_mode_change_ansi(screen, seq->args[i], true);
-#endif
- set_mode(seq, true);
+ set_mode_ecma(seq, true);
}
void
@@ -4975,14 +4739,8 @@ VteTerminalPrivate::SM_DEC(vte::parser::Sequence const& seq)
*
* References: VT525
*/
-#if 0
- unsigned int i;
-
- for (i = 0; i < seq->n_args; ++i)
- screen_mode_change_dec(screen, seq->args[i], true);
-#endif
- decset(seq, false, false, true);
+ set_mode_private(seq, true);
}
void
@@ -5267,7 +5025,7 @@ VteTerminalPrivate::XTERM_RPM(vte::parser::Sequence const& seq)
* References: XTERM
*/
- decset(seq, true, false, false);
+ save_mode_private(seq, false);
}
void
@@ -5311,7 +5069,7 @@ VteTerminalPrivate::XTERM_SPM(vte::parser::Sequence const& seq)
* References: XTERM
*/
- decset(seq, false, true, false);
+ save_mode_private(seq, true);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]