[vte/wip/egmont/bidi: 6/16] emulation: Track BiDi parameters
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/egmont/bidi: 6/16] emulation: Track BiDi parameters
- Date: Sun, 30 Jun 2019 13:12:06 +0000 (UTC)
commit 0a33351609cd372ff18f13f75a9cb26d6d368c5f
Author: Egmont Koblinger <egmont gmail com>
Date: Fri May 31 19:03:56 2019 +0200
emulation: Track BiDi parameters
src/debug.cc | 1 +
src/debug.h | 1 +
src/modes-ecma.hh | 18 +++++++-
src/modes-private.hh | 25 +++++++++++
src/modes.hh | 4 +-
src/parser-cmd.hh | 4 +-
src/parser-csi.hh | 4 +-
src/ring.cc | 11 +++--
src/ring.hh | 9 ++--
src/vte.cc | 106 ++++++++++++++++++++++++++++++++++++++++++--
src/vteinternal.hh | 15 +++++++
src/vterowdata.hh | 3 +-
src/vteseq.cc | 122 ++++++++++++++++++++++++++++++++++++++++++++-------
13 files changed, 288 insertions(+), 35 deletions(-)
---
diff --git a/src/debug.cc b/src/debug.cc
index 5d88833b..afbd7413 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -57,6 +57,7 @@ _vte_debug_init(void)
{ "hyperlink", VTE_DEBUG_HYPERLINK },
{ "modes", VTE_DEBUG_MODES },
{ "emulation", VTE_DEBUG_EMULATION },
+ { "bidi", VTE_DEBUG_BIDI },
};
_vte_debug_flags = g_parse_debug_string (g_getenv("VTE_DEBUG"),
diff --git a/src/debug.h b/src/debug.h
index 41c3665d..92d9d0f9 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -64,6 +64,7 @@ typedef enum {
VTE_DEBUG_HYPERLINK = 1 << 24,
VTE_DEBUG_MODES = 1 << 25,
VTE_DEBUG_EMULATION = 1 << 26,
+ VTE_DEBUG_BIDI = 1 << 27,
} VteDebugFlags;
void _vte_debug_init(void);
diff --git a/src/modes-ecma.hh b/src/modes-ecma.hh
index 617d2985..3c862be7 100644
--- a/src/modes-ecma.hh
+++ b/src/modes-ecma.hh
@@ -38,6 +38,20 @@
*/
MODE(IRM, 4)
+/*
+ * BDSM - Bi-Directional Support Mode
+ *
+ * Reset state is explicit mode, set state is implicit mode
+ *
+ * References: ECMA-48
+ * ECMA TR/53
+ * Terminal-wg/bidi
+ *
+ * Default in ECMA: reset
+ * Default in Terminal-wg/bidi and VTE: set
+ */
+MODE(BDSM, 8)
+
/*
* SRM - local echo send/receive mode
* If reset, characters entered by the keyboard are shown on the
@@ -59,8 +73,8 @@ 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)
+/* DCSM defaults to RESET in ECMA, forced to SET in Terminal-wg/bidi */
+MODE_FIXED(DCSM, 9, ALWAYS_SET)
MODE_FIXED(HEM, 10, ALWAYS_RESET)
MODE_FIXED(PUM, 11, ALWAYS_RESET) /* ECMA-48 § F.4.1 Deprecated */
MODE_FIXED(FEAM, 13, ALWAYS_RESET)
diff --git a/src/modes-private.hh b/src/modes-private.hh
index eb313823..6cefe40a 100644
--- a/src/modes-private.hh
+++ b/src/modes-private.hh
@@ -120,6 +120,31 @@ MODE(DEC_TEXT_CURSOR, 25)
*/
MODE(DEC_APPLICATION_KEYPAD, 66)
+/* Terminal-wg */
+
+/*
+ * Whether to swap the Left and Right arrow keys if the cursor
+ * stands over an RTL paragraph.
+ *
+ * Reference: Terminal-wg/bidi
+ */
+MODE(VTE_BIDI_SWAP_ARROW_KEYS, 1243)
+
+/*
+ * Whether box drawing characters in the U+2500..U+257F range
+ * are to be mirrored in RTL context.
+ *
+ * Reference: Terminal-wg/bidi
+ */
+MODE(VTE_BIDI_BOX_MIRROR, 2500)
+
+/*
+ * Whether BiDi paragraph direction is autodetected.
+ *
+ * Reference: Terminal-wg/bidi
+ */
+MODE(VTE_BIDI_AUTO, 2501)
+
/* XTERM */
MODE(XTERM_MOUSE_X10, 9)
diff --git a/src/modes.hh b/src/modes.hh
index 47d0b415..af218622 100644
--- a/src/modes.hh
+++ b/src/modes.hh
@@ -170,7 +170,8 @@ public:
#undef MODE
#undef MODE_FIXED
- constexpr ECMA() : Self{eSRM} { }
+ constexpr ECMA() : Self{eBDSM,
+ eSRM} { }
}; // class ECMA
@@ -226,6 +227,7 @@ public:
constexpr Private() : Self{eDEC_AUTOWRAP,
eDEC_TEXT_CURSOR,
+ eVTE_BIDI_SWAP_ARROW_KEYS,
eXTERM_ALTBUF_SCROLL,
eXTERM_META_SENDS_ESCAPE} { }
diff --git a/src/parser-cmd.hh b/src/parser-cmd.hh
index 6fcaacc2..c562d7c0 100644
--- a/src/parser-cmd.hh
+++ b/src/parser-cmd.hh
@@ -104,11 +104,13 @@ _VTE_CMD(RM_DEC) /* reset mode dec */
_VTE_CMD(RM_ECMA) /* reset mode ecma */
_VTE_CMD(SCORC) /* SCO restore cursor */
_VTE_CMD(SCOSC) /* SCO save cursor */
+_VTE_CMD(SCP) /* select character path */
_VTE_CMD(SD) /* scroll down */
_VTE_CMD(SD_OR_XTERM_IHMT) /* scroll down or xterm initiate highlight mouse tracking */
_VTE_CMD(SGR) /* select graphics rendition */
_VTE_CMD(SM_DEC) /* set mode dec */
_VTE_CMD(SM_ECMA) /* set mode ecma */
+_VTE_CMD(SPD) /* select presentation directions */
_VTE_CMD(SS2) /* single shift 2 */
_VTE_CMD(SS3) /* single shift 3 */
_VTE_CMD(SUB) /* substitute */
@@ -276,7 +278,6 @@ _VTE_NOP(RLOGIN_MML) /* RLogin music macro language */
_VTE_NOP(SACS) /* set additional character separation */
_VTE_NOP(SAPV) /* select alternative presentation variants */
_VTE_NOP(SCO) /* select character orientation */
-_VTE_NOP(SCP) /* select character path */
_VTE_NOP(SCS) /* set character spacing */
_VTE_NOP(SDS) /* start directed string */
_VTE_NOP(SEE) /* select editing extent */
@@ -289,7 +290,6 @@ _VTE_NOP(SL) /* scroll left */
_VTE_NOP(SLS) /* set line spacing */
_VTE_NOP(SOH) /* start of heading */
_VTE_NOP(SPA) /* start of protected area */
-_VTE_NOP(SPD) /* select presentation directions */
_VTE_NOP(SPH) /* set page home */
_VTE_NOP(SPI) /* spacing increment */
_VTE_NOP(SPL) /* set page limit */
diff --git a/src/parser-csi.hh b/src/parser-csi.hh
index 410d533f..53e1f1f8 100644
--- a/src/parser-csi.hh
+++ b/src/parser-csi.hh
@@ -59,7 +59,7 @@ _VTE_NOQ(SEE, CSI, 'Q', NONE, 0, NONE ) /* select ed
_VTE_NOQ(PPR, CSI, 'Q', NONE, 1, SPACE ) /* page-position-relative */
_VTE_NOQ(PPB, CSI, 'R', NONE, 1, SPACE ) /* page-position-backward */
_VTE_SEQ(SU, CSI, 'S', NONE, 0, NONE ) /* scroll-up */
-_VTE_NOQ(SPD, CSI, 'S', NONE, 1, SPACE ) /* select presentation directions */
+_VTE_SEQ(SPD, CSI, 'S', NONE, 1, SPACE ) /* select presentation directions */
_VTE_NOQ(XTERM_SGFX, CSI, 'S', WHAT, 0, NONE ) /* xterm-sixel-graphics */
_VTE_SEQ(SD_OR_XTERM_IHMT, CSI, 'T', NONE, 0, NONE ) /* scroll-down or
xterm-initiate-highlight-mouse-tracking */
_VTE_NOQ(DTA, CSI, 'T', NONE, 1, SPACE ) /* dimension text area */
@@ -114,7 +114,7 @@ _VTE_NOQ(MC_DEC, CSI, 'i', WHAT, 0, NONE ) /* media-cop
_VTE_NOQ(HPB, CSI, 'j', NONE, 0, NONE ) /* horizontal position backward */
_VTE_NOQ(SPL, CSI, 'j', NONE, 1, SPACE ) /* set page limit */
_VTE_NOQ(VPB, CSI, 'k', NONE, 0, NONE ) /* line position backward */
-_VTE_NOQ(SCP, CSI, 'k', NONE, 1, SPACE ) /* select character path */
+_VTE_SEQ(SCP, CSI, 'k', NONE, 1, SPACE ) /* select character path */
_VTE_SEQ(RM_ECMA, CSI, 'l', NONE, 0, NONE ) /* reset-mode-ecma */
_VTE_SEQ(RM_DEC, CSI, 'l', WHAT, 0, NONE ) /* reset-mode-dec */
_VTE_SEQ(SGR, CSI, 'm', NONE, 0, NONE ) /* select-graphics-rendition */
diff --git a/src/ring.cc b/src/ring.cc
index d7a3bde1..5e8c4533 100644
--- a/src/ring.cc
+++ b/src/ring.cc
@@ -373,6 +373,7 @@ Ring::freeze_row(row_t position,
if (!row->attr.soft_wrapped)
g_string_append_c (buffer, '\n');
record.soft_wrapped = row->attr.soft_wrapped;
+ record.bidi_flags = row->attr.bidi_flags;
_vte_stream_append(m_text_stream, buffer->str, buffer->len);
append_row_record(&record, position);
@@ -435,6 +436,7 @@ Ring::thaw_row(row_t position,
g_string_truncate (buffer, buffer->len - 1);
else
row->attr.soft_wrapped = TRUE;
+ row->attr.bidi_flags = records[0].bidi_flags;
p = buffer->str;
end = p + buffer->len;
@@ -849,7 +851,7 @@ Ring::shrink(row_t max_len)
* Return: the newly added row.
*/
VteRowData*
-Ring::insert(row_t position)
+Ring::insert(row_t position, guint8 bidi_flags)
{
row_t i;
VteRowData* row, tmp;
@@ -872,6 +874,7 @@ Ring::insert(row_t position)
row = get_writable_index(position);
_vte_row_data_clear (row);
+ row->attr.bidi_flags = bidi_flags;
m_end++;
maybe_freeze_one_row();
@@ -921,9 +924,9 @@ Ring::remove(row_t position)
* Return: the newly added row.
*/
VteRowData*
-Ring::append()
+Ring::append(guint8 bidi_flags)
{
- return insert(next());
+ return insert(next(), bidi_flags);
}
@@ -1187,6 +1190,7 @@ Ring::rewrap(column_t columns,
/* Find the boundaries of the next paragraph */
gboolean prev_record_was_soft_wrapped = FALSE;
gboolean paragraph_is_ascii = TRUE;
+ guint8 paragraph_bidi_flags = old_record.bidi_flags;
gsize text_offset = paragraph_start_text_offset;
RowRecord new_record;
column_t col = 0;
@@ -1234,6 +1238,7 @@ Ring::rewrap(column_t columns,
new_record.text_start_offset = text_offset;
new_record.attr_start_offset = attr_offset;
new_record.is_ascii = paragraph_is_ascii;
+ new_record.bidi_flags = paragraph_bidi_flags;
while (paragraph_len > 0) {
/* Wrap one continuous run of identical attributes within the paragraph. */
diff --git a/src/ring.hh b/src/ring.hh
index 1b17ca7a..06ed22fe 100644
--- a/src/ring.hh
+++ b/src/ring.hh
@@ -85,8 +85,8 @@ public:
row_t reset();
void resize(row_t max_rows = kDefaultMaxRows);
void shrink(row_t max_len = kDefaultMaxRows);
- VteRowData* insert(row_t position);
- VteRowData* append();
+ VteRowData* insert(row_t position, guint8 bidi_flags);
+ VteRowData* append(guint8 bidi_flags);
void remove(row_t position);
void drop_scrollback(row_t position);
void set_visible_rows(row_t rows);
@@ -120,6 +120,7 @@ private:
size_t attr_start_offset; /* offset of the first character's attributes */
int soft_wrapped: 1; /* end of line is not '\n' */
int is_ascii: 1; /* for rewrapping speedup: guarantees that line contains 32..126
bytes only. Can be 0 even when ascii only. */
+ guint8 bidi_flags: 4;
} RowRecord;
static_assert(std::is_pod<RowRecord>::value, "Ring::RowRecord is not POD");
@@ -248,8 +249,8 @@ static inline auto _vte_ring_get_hyperlink_at_position (VteRing *ring, gulong po
static inline long _vte_ring_reset (VteRing *ring) { return ring->reset(); }
static inline void _vte_ring_resize (VteRing *ring, gulong max_rows) { ring->resize(max_rows); }
static inline void _vte_ring_shrink (VteRing *ring, gulong max_len) { ring->shrink(max_len); }
-static inline VteRowData *_vte_ring_insert (VteRing *ring, gulong position) { return ring->insert(position);
}
-static inline VteRowData *_vte_ring_append (VteRing *ring) { return ring->append(); }
+static inline VteRowData *_vte_ring_insert (VteRing *ring, gulong position, guint8 bidi_flags) { return
ring->insert(position, bidi_flags); }
+static inline VteRowData *_vte_ring_append (VteRing *ring, guint8 bidi_flags) { return
ring->append(bidi_flags); }
static inline void _vte_ring_remove (VteRing *ring, gulong position) { ring->remove(position); }
static inline void _vte_ring_drop_scrollback (VteRing *ring, gulong position) {
ring->drop_scrollback(position); }
static inline void _vte_ring_set_visible_rows (VteRing *ring, gulong rows) { ring->set_visible_rows(rows); }
diff --git a/src/vte.cc b/src/vte.cc
index 8c346e52..098cd929 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -139,11 +139,11 @@ Terminal::ring_insert(vte::grid::row_t position,
bool const not_default_bg = (m_color_defaults.attr.back() != VTE_DEFAULT_BG);
while (G_UNLIKELY (_vte_ring_next (ring) < position)) {
- row = _vte_ring_append (ring);
+ row = _vte_ring_append (ring, get_bidi_flags());
if (not_default_bg)
_vte_row_data_fill (row, &m_color_defaults, m_column_count);
}
- row = _vte_ring_insert (ring, position);
+ row = _vte_ring_insert (ring, position, get_bidi_flags());
if (fill && not_default_bg)
_vte_row_data_fill (row, &m_color_defaults, m_column_count);
return row;
@@ -487,7 +487,8 @@ Terminal::set_hard_wrapped(vte::grid::row_t row)
row_data->attr.soft_wrapped = false;
}
-/* Sets the line ending to soft wrapped (overflow to the next line). */
+/* Sets the line ending to soft wrapped (overflow to the next line).
+ * Also makes sure that the joined new paragraph receives the first one's bidi flags. */
void
Terminal::set_soft_wrapped(vte::grid::row_t row)
{
@@ -497,7 +498,24 @@ Terminal::set_soft_wrapped(vte::grid::row_t row)
VteRowData *row_data = find_row_data_writable(row);
g_assert(row_data != nullptr);
+ if (row_data->attr.soft_wrapped)
+ return;
+
row_data->attr.soft_wrapped = true;
+
+ /* Each paragraph has to have consistent bidi flags across all of its rows.
+ * Spread the first paragraph's flags across the second one (if they differ). */
+ guint8 bidi_flags = row_data->attr.bidi_flags;
+ vte::grid::row_t i = row + 1;
+ row_data = find_row_data_writable(i);
+ if (row_data != nullptr && row_data->attr.bidi_flags != bidi_flags) {
+ do {
+ row_data->attr.bidi_flags = bidi_flags;
+ if (!row_data->attr.soft_wrapped)
+ break;
+ row_data = find_row_data_writable(++i);
+ } while (row_data != nullptr);
+ }
}
/* Determine the width of the portion of the preedit string which lies
@@ -2892,6 +2910,8 @@ Terminal::insert_char(gunichar c,
row = ensure_row();
set_soft_wrapped(m_screen->cursor.row);
cursor_down(false);
+ ensure_row();
+ apply_bidi_attributes(m_screen->cursor.row, row->attr.bidi_flags, VTE_BIDI_FLAG_ALL);
} else {
/* Don't wrap, stay at the rightmost column. */
col = m_screen->cursor.col =
@@ -3027,6 +3047,84 @@ not_inserted:
m_line_wrapped = line_wrapped;
}
+guint8
+Terminal::get_bidi_flags() const noexcept
+{
+ return (m_modes_ecma.BDSM() ? VTE_BIDI_FLAG_IMPLICIT : 0) |
+ (m_bidi_rtl ? VTE_BIDI_FLAG_RTL : 0) |
+ (m_modes_private.VTE_BIDI_AUTO() ? VTE_BIDI_FLAG_AUTO : 0) |
+ (m_modes_private.VTE_BIDI_BOX_MIRROR() ? VTE_BIDI_FLAG_BOX_MIRROR : 0);
+}
+
+/* Apply the specified BiDi parameters on the paragraph beginning at the specified line. */
+void
+Terminal::apply_bidi_attributes(vte::grid::row_t start, guint8 bidi_flags, guint8 bidi_flags_mask)
+{
+ vte::grid::row_t row = start;
+ VteRowData *rowdata;
+
+ bidi_flags &= bidi_flags_mask;
+
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "Applying BiDi parameters from row %ld.\n", row);
+
+ rowdata = _vte_ring_index_writable (m_screen->row_data, row);
+ if (rowdata == nullptr || (rowdata->attr.bidi_flags & bidi_flags_mask) == bidi_flags) {
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "BiDi parameters didn't change for this paragraph.\n");
+ return;
+ }
+
+ while (true) {
+ rowdata->attr.bidi_flags &= ~bidi_flags_mask;
+ rowdata->attr.bidi_flags |= bidi_flags;
+
+ if (!rowdata->attr.soft_wrapped)
+ break;
+
+ rowdata = _vte_ring_index_writable (m_screen->row_data, row + 1);
+ if (rowdata == nullptr)
+ break;
+ row++;
+ }
+
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "Applied BiDi parameters to rows %ld..%ld.\n", start, row);
+
+ invalidate_rows(start, row);
+}
+
+/* Apply the current BiDi parameters covered by bidi_flags_mask on the current paragraph
+ * if the cursor is at the first position of this paragraph. */
+void
+Terminal::maybe_apply_bidi_attributes(guint8 bidi_flags_mask)
+{
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "Maybe applying BiDi parameters on current paragraph.\n");
+
+ if (m_screen->cursor.col != 0) {
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "No, cursor not in first column.\n");
+ return;
+ }
+
+ auto row = m_screen->cursor.row;
+
+ if (row > _vte_ring_delta (m_screen->row_data)) {
+ const VteRowData *rowdata = _vte_ring_index (m_screen->row_data, row - 1);
+ if (rowdata != nullptr && rowdata->attr.soft_wrapped) {
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "No, we're not after a hard wrap.\n");
+ return;
+ }
+ }
+
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "Yes, applying.\n");
+
+ apply_bidi_attributes (row, get_bidi_flags(), bidi_flags_mask);
+}
+
static void
reaper_child_exited_cb(VteReaper *reaper,
int ipid,
@@ -9940,6 +10038,8 @@ Terminal::reset(bool clear_tabstops,
/* Reset the saved cursor. */
save_cursor(&m_normal_screen);
save_cursor(&m_alternate_screen);
+ /* BiDi */
+ m_bidi_rtl = FALSE;
/* Cause everything to be redrawn (or cleared). */
invalidate_all();
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 757e6674..6399bcfc 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -86,6 +86,14 @@ enum {
VTE_SGR_COLOR_SPEC_LEGACY = 5
};
+enum {
+ VTE_BIDI_FLAG_IMPLICIT = 1 << 0,
+ VTE_BIDI_FLAG_RTL = 1 << 1,
+ VTE_BIDI_FLAG_AUTO = 1 << 2,
+ VTE_BIDI_FLAG_BOX_MIRROR = 1 << 3,
+ VTE_BIDI_FLAG_ALL = (1 << 4) - 1,
+};
+
struct vte_regex_and_flags {
VteRegex *regex;
guint32 match_flags;
@@ -604,6 +612,9 @@ public:
const char *m_hyperlink_hover_uri; /* data is owned by the ring */
long m_hyperlink_auto_id;
+ /* BiDi parameters outside of ECMA and DEC private modes */
+ guint m_bidi_rtl : 1;
+
public:
// FIXMEchpe inline!
@@ -656,6 +667,10 @@ public:
void invalidate_match_span();
void invalidate_all();
+ guint8 get_bidi_flags() const noexcept;
+ void apply_bidi_attributes(vte::grid::row_t start, guint8 bidi_flags, guint8 bidi_flags_mask);
+ void maybe_apply_bidi_attributes(guint8 bidi_flags_mask);
+
void reset_update_rects();
bool invalidate_dirty_rects_and_process_updates();
void time_process_incoming();
diff --git a/src/vterowdata.hh b/src/vterowdata.hh
index 9d4b2767..12cbf311 100644
--- a/src/vterowdata.hh
+++ b/src/vterowdata.hh
@@ -36,7 +36,8 @@ G_BEGIN_DECLS
*/
typedef struct _VteRowAttr {
- guint8 soft_wrapped: 1;
+ guint8 soft_wrapped : 1;
+ guint8 bidi_flags : 4;
} VteRowAttr;
static_assert(sizeof (VteRowAttr) == 1, "VteRowAttr has wrong size");
diff --git a/src/vteseq.cc b/src/vteseq.cc
index c5f45f69..9c3e2ffb 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -315,6 +315,7 @@ Terminal::clear_current_line()
/* Add enough cells to the end of the line to fill out the row. */
_vte_row_data_fill (rowdata, &m_color_defaults, m_column_count);
set_hard_wrapped(m_screen->cursor.row);
+ rowdata->attr.bidi_flags = get_bidi_flags();
/* Repaint this row. */
invalidate_row(m_screen->cursor.row);
}
@@ -342,6 +343,7 @@ Terminal::clear_above_current()
/* Add new cells until we fill the row. */
_vte_row_data_fill (rowdata, &m_color_defaults, m_column_count);
set_hard_wrapped(i);
+ rowdata->attr.bidi_flags = get_bidi_flags();
/* Repaint the row. */
invalidate_row(i);
}
@@ -469,6 +471,13 @@ Terminal::set_mode_ecma(vte::parser::Sequence const& seq,
continue;
m_modes_ecma.set(mode, set);
+
+ if (mode == m_modes_ecma.eBDSM) {
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "BiDi %s mode\n",
+ set ? "implicit" : "explicit");
+ maybe_apply_bidi_attributes(VTE_BIDI_FLAG_IMPLICIT);
+ }
}
}
@@ -597,6 +606,20 @@ Terminal::set_mode_private(int mode,
feed_focus_event_initial();
break;
+ case vte::terminal::modes::Private::eVTE_BIDI_BOX_MIRROR:
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "BiDi box drawing mirroring %s\n",
+ set ? "enabled" : "disabled");
+ maybe_apply_bidi_attributes(VTE_BIDI_FLAG_BOX_MIRROR);
+ break;
+
+ case vte::terminal::modes::Private::eVTE_BIDI_AUTO:
+ _vte_debug_print(VTE_DEBUG_BIDI,
+ "BiDi dir autodetection %s\n",
+ set ? "enabled" : "disabled");
+ maybe_apply_bidi_attributes(VTE_BIDI_FLAG_AUTO);
+ break;
+
default:
break;
}
@@ -745,6 +768,8 @@ Terminal::clear_below_current()
_vte_row_data_fill(rowdata, &m_color_defaults, m_column_count);
}
set_hard_wrapped(i);
+ if (i > m_screen->cursor.row)
+ rowdata->attr.bidi_flags = get_bidi_flags();
/* Repaint this row. */
invalidate_row(i);
}
@@ -1030,6 +1055,7 @@ Terminal::line_feed()
{
ensure_cursor_is_onscreen();
cursor_down(true);
+ maybe_apply_bidi_attributes(VTE_BIDI_FLAG_ALL);
}
void
@@ -4754,7 +4780,7 @@ Terminal::DECSTBM(vte::parser::Sequence const& seq)
} else {
/* Maybe extend the ring -- bug 710483 */
while (_vte_ring_next(m_screen->row_data) < m_screen->insert_delta + m_row_count)
- _vte_ring_insert(m_screen->row_data, _vte_ring_next(m_screen->row_data));
+ _vte_ring_insert(m_screen->row_data, _vte_ring_next(m_screen->row_data),
get_bidi_flags());
}
home_cursor();
@@ -4963,8 +4989,11 @@ Terminal::DL(vte::parser::Sequence const& seq)
* DL - delete-line
* Delete lines starting from the active line (presentation).
*
- * This function is affected by the DCSM, TSM and VEM modes,
- * and the SLH and SEE functions.
+ * Depending on DCSM, this function works on the presentation
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
+ *
+ * Also affected by TSM and VEM modes, and the SLH and SEE
+ * functions.
*
* Arguments:
* args[0]: number of lines to delete
@@ -4973,6 +5002,7 @@ Terminal::DL(vte::parser::Sequence const& seq)
* args[0]: 1
*
* References: ECMA-48 § 8.3.32
+ * Terminal-wg/bidi
*/
#if 0
unsigned int num = 1;
@@ -5300,9 +5330,10 @@ Terminal::EA(vte::parser::Sequence const& seq)
* ERM is reset, erases all areas.
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.37
+ * Terminal-wg/bidi
*/
switch (seq.collect1(0)) {
@@ -5333,9 +5364,10 @@ Terminal::ECH(vte::parser::Sequence const& seq)
* ERM is reset, erases all characters.
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.38
+ * Terminal-wg/bidi
*/
#if 0
unsigned int num = 1;
@@ -5384,10 +5416,11 @@ Terminal::ED(vte::parser::Sequence const& seq)
* ERM is reset, erases all characters.
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.39
* VT525
+ * Terminal-wg/bidi
*/
erase_in_display(seq);
@@ -5415,9 +5448,10 @@ Terminal::EF(vte::parser::Sequence const& seq)
* ERM is reset, erases all characters.
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.40
+ * Terminal-wg/bidi
*/
}
@@ -5444,10 +5478,11 @@ Terminal::EL(vte::parser::Sequence const& seq)
* ERM is reset, erases all characters.
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.41
* VT525
+ * Terminal-wg/bidi
*/
erase_in_line(seq);
@@ -5899,12 +5934,13 @@ Terminal::ICH(vte::parser::Sequence const& seq)
* args[0]: 1
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
* Also affected by HEM mode, and the SLH, and SEE functions.
*
* References: ECMA-48 §8.3.64
* VT525
+ * Terminal-wg/bidi
*/
#if 0
unsigned int num = 1;
@@ -5982,12 +6018,13 @@ Terminal::IL(vte::parser::Sequence const& seq)
* args[0]: 1
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* Also affected by the TSM and VEM modes,
* and the SLH and SEE functions.
*
* References: ECMA-48 § 8.3.67
+ * Terminal-wg/bidi
*/
#if 0
unsigned int num = 1;
@@ -6915,19 +6952,46 @@ Terminal::SCP(vte::parser::Sequence const& seq)
*
* Arguments:
* args[0]: path
+ * 0 in Terminal-wg/bidi and VTE = terminal's default
* 1 = LTR or TTB (for horizontal/vertical line orientation)
* 2 = RTL or BTT (for horizontal/vertical line orientation)
* args[1]: effect
- * 0 = implementation-defined
+ * 0 in ECMA = implementation-defined
+ * 0 in Terminal-wg/bidi and VTE = see Terminal-wg/bidi
* 1 = ...
* 2 = ...
*
* Defaults:
- * args[0]: no default
- * args[1]: no default
+ * args[0] in ECMA: no default
+ * args[1] in ECMA: no default
+ * args[0] in Terminal-wg/bidi: 0
+ * args[1] in Terminal-wg/bidi: 0
*
* References: ECMA-48 § 8.3.111
+ * Terminal-wg/bidi
*/
+
+ auto const param = seq.collect1(0);
+ switch (param) {
+ case -1:
+ case 0:
+ /* FIXME switch to the emulator's default, once we have that concept */
+ m_bidi_rtl = FALSE;
+ _vte_debug_print(VTE_DEBUG_BIDI, "BiDi: default direction restored\n");
+ break;
+ case 1:
+ m_bidi_rtl = FALSE;
+ _vte_debug_print(VTE_DEBUG_BIDI, "BiDi: switch to LTR\n");
+ break;
+ case 2:
+ m_bidi_rtl = TRUE;
+ _vte_debug_print(VTE_DEBUG_BIDI, "BiDi: switch to RTL\n");
+ break;
+ default:
+ return;
+ }
+
+ maybe_apply_bidi_attributes(VTE_BIDI_FLAG_RTL);
}
void
@@ -7268,9 +7332,10 @@ Terminal::SLH(vte::parser::Sequence const& seq)
* args[0]: no default
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.122
+ * Terminal-wg/bidi
*/
}
@@ -7287,9 +7352,10 @@ Terminal::SLL(vte::parser::Sequence const& seq)
* args[0]: no default
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.123
+ * Terminal-wg/bidi
*/
}
@@ -7395,7 +7461,27 @@ Terminal::SPD(vte::parser::Sequence const& seq)
* args[1]: 0
*
* References: ECMA-48 § 8.3.130
+ * Terminal-wg/bidi
*/
+
+ auto const param = seq.collect1(0);
+ switch (param) {
+ case -1:
+ case 0:
+ m_bidi_rtl = FALSE;
+ _vte_debug_print(VTE_DEBUG_BIDI, "BiDi: switch to LTR\n");
+ break;
+ case 3:
+ m_bidi_rtl = TRUE;
+ _vte_debug_print(VTE_DEBUG_BIDI, "BiDi: switch to RTL\n");
+ break;
+ default:
+ return;
+ }
+
+ maybe_apply_bidi_attributes(VTE_BIDI_FLAG_RTL);
+
+ /* FIXME maybe apply to all the onscreen lines? */
}
void
@@ -7411,9 +7497,10 @@ Terminal::SPH(vte::parser::Sequence const& seq)
* args[0]: no default
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.131
+ * Terminal-wg/bidi
*/
}
@@ -7449,9 +7536,10 @@ Terminal::SPL(vte::parser::Sequence const& seq)
* args[0]: no default
*
* Depending on DCSM, this function works on the presentation
- * or data position.
+ * or data position. Terminal-wg/bidi forces DCSM to DATA.
*
* References: ECMA-48 § 8.3.133
+ * Terminal-wg/bidi
*/
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]