diff options
author | Christian Persch <chpe@src.gnome.org> | 2018-03-04 23:22:26 +0100 |
---|---|---|
committer | Christian Persch <chpe@src.gnome.org> | 2018-03-04 23:22:26 +0100 |
commit | cac7b40b507c8ef705c0d7a3c2fee8a4bc3ee6ef (patch) | |
tree | 4a6cdda0a3ce439c8d11f174d0ea3894701de118 | |
parent | bac521b55ec8df9de486c318094fa3d016b7ec8a (diff) | |
download | vte-cac7b40b507c8ef705c0d7a3c2fee8a4bc3ee6ef.tar.gz |
emulation: Implement DECRQCRA
This will be used in the test suite later.
https://bugzilla.gnome.org/show_bug.cgi?id=745045
-rw-r--r-- | src/caps-list.hh | 2 | ||||
-rw-r--r-- | src/vte.cc | 29 | ||||
-rw-r--r-- | src/vteinternal.hh | 5 | ||||
-rw-r--r-- | src/vteseq-list.hh | 1 | ||||
-rw-r--r-- | src/vteseq.cc | 89 |
5 files changed, 126 insertions, 0 deletions
diff --git a/src/caps-list.hh b/src/caps-list.hh index cc751916..0528d7bc 100644 --- a/src/caps-list.hh +++ b/src/caps-list.hh @@ -294,6 +294,8 @@ static const vte_matcher_entry_t entries[] = { ENTRY(OSC "2L;%s" BEL, set_text_property_2L), ENTRY(OSC "21;%s" ST, set_text_property_21), ENTRY(OSC "2L;%s" ST, set_text_property_2L), + + ENTRY(CSI "%m*y", checksum_rectangular_area), }; #undef ENTRY @@ -6156,6 +6156,35 @@ VteTerminalPrivate::get_selected_text(GArray *attributes) attributes); } +#ifdef VTE_DEBUG +unsigned int +VteTerminalPrivate::checksum_area(vte::grid::row_t start_row, + vte::grid::column_t start_col, + vte::grid::row_t end_row, + vte::grid::column_t end_col) +{ + unsigned int checksum = 0; + + auto text = get_text(start_row, start_col, end_row, end_col, + true /* block */, false /* wrap */, + true /* trailing whitespace */, + nullptr /* not interested in attributes */); + if (text == nullptr) + return checksum; + + char const* end = (char const*)text->str + text->len; + for (char const *p = text->str; p < end; p = g_utf8_next_char(p)) { + auto const c = g_utf8_get_char(p); + if (c == '\n') + continue; + checksum += c; + } + g_string_free(text, true); + + return checksum & 0xffff; +} +#endif /* VTE_DEBUG */ + /* * Compares the visual attributes of a VteCellAttr for equality, but ignores * attributes that tend to change from character to character or are otherwise diff --git a/src/vteinternal.hh b/src/vteinternal.hh index a58a0056..2d02f8d7 100644 --- a/src/vteinternal.hh +++ b/src/vteinternal.hh @@ -1356,6 +1356,11 @@ public: int osc, char const *terminator); + unsigned int checksum_area(vte::grid::row_t start_row, + vte::grid::column_t start_col, + vte::grid::row_t end_row, + vte::grid::column_t end_col); + void subscribe_accessible_events(); void select_text(vte::grid::column_t start_col, vte::grid::row_t start_row, diff --git a/src/vteseq-list.hh b/src/vteseq-list.hh index 1dda4486..af9fc893 100644 --- a/src/vteseq-list.hh +++ b/src/vteseq-list.hh @@ -1,3 +1,4 @@ +SEQUENCE_HANDLER(checksum_rectangular_area) SEQUENCE_HANDLER(ansi_conformance_level_1) SEQUENCE_HANDLER(ansi_conformance_level_2) SEQUENCE_HANDLER(ansi_conformance_level_3) diff --git a/src/vteseq.cc b/src/vteseq.cc index 4da48c49..218bedf4 100644 --- a/src/vteseq.cc +++ b/src/vteseq.cc @@ -189,6 +189,95 @@ VteTerminalPrivate::emit_resize_window(guint columns, /* Some common functions */ +void +VteTerminalPrivate::seq_checksum_rectangular_area(vte::parser::Params const& params) +{ + /* + * DECRQCRA - request checksum of rectangular area + * Computes a simple checksum of the characters in the rectangular + * area. args[0] is an identifier, which the response must use. + * args[1] is the page number; if it's 0 or default then the + * checksum is computed over all pages; if it's greater than the + * number of pages, then the checksum is computed only over the + * last page. args[2]..args[5] describe the area to compute the + * checksum from, denoting the top, left, bottom, right, resp + * (1-based). It's required that top ≤ bottom, and left ≤ right. + * These coordinates are interpreted according to origin mode. + * + * NOTE: Since this effectively allows to read the screen + * (by using a 1x1 rectangle on each cell), we normally only + * send a dummy reply, and only reply with the actual checksum + * when in test mode. + * + * Defaults: + * args[0]: no default + * args[1]: 0 + * args[2]: 1 + * args[3]: no default (?) + * args[4]: height of current page + * args[5]: width of current page + * + * Reply: DECCKSR + * @args[0]: the identifier from the request + * DATA: the checksum as a 4-digit hex number + * + * References: VT525 + * XTERM + */ + + char buf[32]; + gsize len; + + int id = params.number_or_default_at(0, 0); + +#ifndef VTE_DEBUG + /* Send a dummy reply */ + len = g_snprintf(buf, sizeof(buf), "\eP%d!~%04X\e\\", id, 0); + feed_child(buf, len); +#else + + /* Not in test mode? Send a dummy reply */ + if (!g_test_mode) { + len = g_snprintf(buf, sizeof(buf), "\eP%d!~%04X\e\\", id, 0); + feed_child(buf, len); + return; + } + + /* We only support 1 'page', so ignore args[1] */ + + int top = params.number_or_default_at(2, 1); + int left = params.number_or_default_at(3, 1); /* use 1 as default here */ + int bottom = params.number_or_default_at(4, m_row_count); + int right = params.number_or_default_at(5, m_column_count); + + top = CLAMP(top, 1, m_row_count); + left = CLAMP(left, 1, m_column_count); + bottom = CLAMP(bottom, 1, m_row_count); + right = CLAMP (right, 1, m_column_count); + + if (m_origin_mode && + m_scrolling_restricted) { + top += m_scrolling_region.start; + + bottom += m_scrolling_region.start; + bottom = MIN(bottom, m_scrolling_region.end); + + } + + unsigned int checksum; + if (bottom < top || right < left) + checksum = 0; /* empty area */ + else + checksum = checksum_area(top -1 + m_screen->insert_delta, + left - 1, + bottom - 1 + m_screen->insert_delta, + right - 1); + + len = g_snprintf(buf, sizeof(buf), "\eP%d!~%04X\e\\", id, checksum); + feed_child(buf, len); +#endif /* VTE_DEBUG */ +} + /* In Xterm, upon printing a character in the last column the cursor doesn't * advance. It's special cased that printing the following letter will first * wrap to the next row. |