[vte] emulation: Drop ISO-2022 support
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] emulation: Drop ISO-2022 support
- Date: Sat, 22 Nov 2014 18:23:23 +0000 (UTC)
commit 02da6534a721f09619962ca24aa287b2a36bd630
Author: Egmont Koblinger <egmont gmail com>
Date: Sat Nov 22 19:16:56 2014 +0100
emulation: Drop ISO-2022 support
https://bugzilla.gnome.org/show_bug.cgi?id=732586
src/Makefile.am | 38 +--
src/caps.c | 10 +-
src/interpret.c | 5 +-
src/iso2022.c | 1700 +---------------------------------------------------
src/iso2022.h | 22 +-
src/table.c | 7 +-
src/vte-private.h | 13 +-
src/vte.c | 139 +++--
src/vteseq-n.gperf | 10 +-
src/vteseq.c | 60 ++-
10 files changed, 187 insertions(+), 1817 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index bf50886..1c533da 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,15 +29,6 @@ lib_LTLIBRARIES = libvte- VTE_API_MAJOR_VERSION@ VTE_API_MINOR_VERSION@.la
EXTRA_libvte_ VTE_API_MAJOR_VERSION@_ VTE_API_MINOR_VERSION@_la_SOURCES = \
box_drawing_generate.sh \
marshal.list \
- mkunitables.sh \
- unitable.CNS11643 \
- unitable.CP437 \
- unitable.GB12345 \
- unitable.GB2312 \
- unitable.JIS0201 \
- unitable.JIS0208 \
- unitable.JIS0212 \
- unitable.KSX1001 \
vteseq-n.gperf \
vteseq-n.c \
vtetypebuiltins.c.template \
@@ -329,7 +320,7 @@ TEST_SH = \
$(NULL)
EXTRA_DIST += $(TEST_SH)
-check_PROGRAMS = dumpkeys iso2022 reflect-text-view reflect-vte mev table xticker vteconv
+check_PROGRAMS = dumpkeys reflect-text-view reflect-vte mev table xticker vteconv
TESTS = table vteconv $(TEST_SH)
reflect_text_view_CPPFLAGS = -DUSE_TEXT_VIEW $(AM_CPPFLAGS)
@@ -372,33 +363,6 @@ interpret_LDADD = \
$(GLIB_LIBS) \
$(GOBJECT_LIBS)
-iso2022_SOURCES = \
- buffer.h \
- caps.c \
- caps.h \
- debug.c \
- debug.h \
- iso2022.c \
- iso2022.h \
- matcher.c \
- matcher.h \
- table.c \
- table.h \
- vteconv.c \
- vteconv.h \
- vtetree.c \
- vtetree.h
-iso2022_CPPFLAGS = \
- -DISO2022_MAIN \
- $(AM_CPPFLAGS)
-iso2022_CFLAGS = \
- $(GLIB_CFLAGS) \
- $(GTK_CFLAGS) \
- $(AM_CFLAGS)
-iso2022_LDADD = \
- $(GLIB_LIBS) \
- $(GOBJECT_LIBS)
-
slowcat_SOURCES = \
slowcat.c \
$(NULL)
diff --git a/src/caps.c b/src/caps.c
index 7ace1ad..edeb97d 100644
--- a/src/caps.c
+++ b/src/caps.c
@@ -54,6 +54,8 @@ const char _vte_xterm_capability_strings[] =
ENTRY(VT, "vertical-tab")
ENTRY(FF, "form-feed")
ENTRY(CR, "carriage-return")
+ ENTRY(SO, "shift-out")
+ ENTRY(SI, "shift-in")
ENTRY(DEL, "backspace")
ENTRY(ESC " F", "7-bit-controls")
@@ -73,8 +75,12 @@ const char _vte_xterm_capability_strings[] =
ENTRY(ESC "%%@", "default-character-set")
ENTRY(ESC "%%G", "utf-8-character-set")
- ENTRY(ESC "(0", "alternate-character-set-start")
- ENTRY(ESC "(B", "alternate-character-set-end")
+ ENTRY(ESC "(0", "designate-g0-line-drawing")
+ ENTRY(ESC "(A", "designate-g0-british")
+ ENTRY(ESC "(B", "designate-g0-plain")
+ ENTRY(ESC ")0", "designate-g1-line-drawing")
+ ENTRY(ESC ")A", "designate-g1-british")
+ ENTRY(ESC ")B", "designate-g1-plain")
ENTRY(ESC "7", "save-cursor")
ENTRY(ESC "8", "restore-cursor")
diff --git a/src/interpret.c b/src/interpret.c
index 807c136..c192aa5 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -72,7 +72,7 @@ main(int argc, char **argv)
matcher = _vte_matcher_new();
- subst = _vte_iso2022_state_new(NULL, VTE_ISO2022_DEFAULT_UTF8_AMBIGUOUS_WIDTH, NULL, NULL);
+ subst = _vte_iso2022_state_new(NULL);
for (;;) {
l = read (infile, buf, sizeof (buf));
@@ -107,9 +107,6 @@ main(int argc, char **argv)
if (tmp == NULL) {
gunichar c;
c = g_array_index(array, gunichar, i);
- if (VTE_ISO2022_HAS_ENCODED_WIDTH(c)) {
- c &= ~VTE_ISO2022_ENCODED_WIDTH_MASK;
- }
if (c < 32) {
g_print("`^%c'\n", c + 64);
} else
diff --git a/src/iso2022.c b/src/iso2022.c
index 0989082..44c492f 100644
--- a/src/iso2022.c
+++ b/src/iso2022.c
@@ -16,6 +16,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/*
+ * This file used to contain a full iso2022 decoder which was removed for
+ * version 0.40. Now it only performs input conversion from the given
+ * character encoding. TODO: probably this layer could be removed completely.
+ */
+
#include <config.h>
#include <sys/types.h>
#include <errno.h>
@@ -26,9 +32,7 @@
#include "debug.h"
#include "buffer.h"
#include "iso2022.h"
-#include "matcher.h"
#include "vteconv.h"
-#include "vtetree.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
@@ -37,741 +41,21 @@
#include <gdk/gdkkeysyms.h>
-/* Maps which jive with XTerm's ESC ()*+ ? sequences, RFC 1468. Add the
- * PC437 map because despite knowing that XTerm doesn't support it, certain
- * applications try to use it anyway. */
-#define NARROW_MAPS "012AB4C5RQKYE6ZH7=" "J" "U"
-/* Maps which jive with RFC 1468's ESC $ ? sequences. */
-#define WIDE_MAPS "@B"
-/* Maps which jive with RFC 1557/1922/2237's ESC $ ()*+ ? sequences. */
-#define WIDE_GMAPS "C" "AGHIJKLM" "D"
-/* Fudge factor we add to wide map identifiers to keep them distinct. */
-#define WIDE_FUDGE 0x100000
/* An invalid codepoint. */
#define INVALID_CODEPOINT 0xFFFD
-struct _vte_iso2022_map16 {
- guint16 from, to;
-};
-
-struct _vte_iso2022_map32 {
- guint32 from, to;
-};
-
-struct _vte_iso2022_block {
- enum {
- _vte_iso2022_cdata,
- _vte_iso2022_preserve,
- _vte_iso2022_control
- } type;
- gulong start, end;
-};
-
struct _vte_iso2022_state {
- gboolean nrc_enabled;
- int current, override;
- gunichar g[4];
const gchar *codeset, *native_codeset, *utf8_codeset, *target_codeset;
- gint ambiguous_width;
- gint utf8_ambiguous_width;
VteConv conv;
- _vte_iso2022_codeset_changed_cb_fn codeset_changed;
- gpointer codeset_changed_data;
VteByteArray *buffer;
};
-/* DEC Special Character and Line Drawing Set. VT100 and higher (per XTerm
- * docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_0[] = {
- { 96, 0x25c6}, /* diamond */
- {'a', 0x2592}, /* checkerboard */
- {'b', 0x2409}, /* HT symbol */
- {'c', 0x240c}, /* FF symbol */
- {'d', 0x240d}, /* CR symbol */
- {'e', 0x240a}, /* LF symbol */
- {'f', 0x00b0}, /* degree */
- {'g', 0x00b1}, /* plus/minus */
- {'h', 0x2424}, /* NL symbol */
- {'i', 0x240b}, /* VT symbol */
- {'j', 0x2518}, /* downright corner */
- {'k', 0x2510}, /* upright corner */
- {'l', 0x250c}, /* upleft corner */
- {'m', 0x2514}, /* downleft corner */
- {'n', 0x253c}, /* cross */
- {'o', 0x23ba}, /* scan line 1/9 */
- {'p', 0x23bb}, /* scan line 3/9 */
- {'q', 0x2500}, /* horizontal line (also scan line 5/9) */
- {'r', 0x23bc}, /* scan line 7/9 */
- {'s', 0x23bd}, /* scan line 9/9 */
- {'t', 0x251c}, /* left t */
- {'u', 0x2524}, /* right t */
- {'v', 0x2534}, /* bottom t */
- {'w', 0x252c}, /* top t */
- {'x', 0x2502}, /* vertical line */
- {'y', 0x2264}, /* <= */
- {'z', 0x2265}, /* >= */
- {'{', 0x03c0}, /* pi */
- {'|', 0x2260}, /* not equal */
- {'}', 0x00a3}, /* pound currency sign */
- {'~', 0x00b7}, /* bullet */
-};
-/* United Kingdom. VT100 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_A[] = {
- {'$', GDK_KEY_sterling},
-};
-/* US-ASCII (no conversions). VT100 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_B[] = {
- {0, 0},
-};
-/* Dutch. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_4[] = {
- {'#', GDK_KEY_sterling},
- {'@', GDK_KEY_threequarters},
- {'[', GDK_KEY_ydiaeresis},
- {'\\', GDK_KEY_onehalf},
- {']', GDK_KEY_bar}, /* FIXME? not in XTerm 170 */
- {'{', GDK_KEY_diaeresis},
- {'|', 0x192}, /* f with hook (florin) */ /* FIXME? not in XTerm 170 */
- {'}', GDK_KEY_onequarter},
- {'~', GDK_KEY_acute},
-};
-/* Finnish. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_C[] = {
- {'[', GDK_KEY_Adiaeresis},
- {'\\', GDK_KEY_Odiaeresis},
- {']', GDK_KEY_Aring},
- {'^', GDK_KEY_Udiaeresis},
- {'`', GDK_KEY_eacute},
- {'{', GDK_KEY_adiaeresis},
- {'|', GDK_KEY_odiaeresis},
- {'}', GDK_KEY_aring},
- {'~', GDK_KEY_udiaeresis},
-};
-/* French. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_R[] = {
- {'#', GDK_KEY_sterling},
- {'@', GDK_KEY_agrave},
- {'[', GDK_KEY_degree},
- {'\\', GDK_KEY_ccedilla},
- {']', GDK_KEY_section},
- {'{', GDK_KEY_eacute},
- {'|', GDK_KEY_ugrave},
- {'}', GDK_KEY_egrave},
- {'~', GDK_KEY_diaeresis},
-};
-/* French Canadian. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_Q[] = {
- {'@', GDK_KEY_agrave},
- {'[', GDK_KEY_acircumflex},
- {'\\', GDK_KEY_ccedilla},
- {']', GDK_KEY_ecircumflex},
- {'^', GDK_KEY_icircumflex},
- {'`', GDK_KEY_ocircumflex},
- {'{', GDK_KEY_eacute},
- {'|', GDK_KEY_ugrave},
- {'}', GDK_KEY_egrave},
- {'~', GDK_KEY_ucircumflex},
-};
-/* German. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_K[] = {
- {'@', GDK_KEY_section},
- {'[', GDK_KEY_Adiaeresis},
- {'\\', GDK_KEY_Odiaeresis},
- {']', GDK_KEY_Udiaeresis},
- {'{', GDK_KEY_adiaeresis},
- {'|', GDK_KEY_odiaeresis},
- {'}', GDK_KEY_udiaeresis},
- {'~', GDK_KEY_ssharp},
-};
-/* Italian. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_Y[] = {
- {'#', GDK_KEY_sterling},
- {'@', GDK_KEY_section},
- {'[', GDK_KEY_degree},
- {'\\', GDK_KEY_ccedilla},
- {']', GDK_KEY_eacute},
- {'`', GDK_KEY_ugrave},
- {'{', GDK_KEY_agrave},
- {'|', GDK_KEY_ograve},
- {'}', GDK_KEY_egrave},
- {'~', GDK_KEY_igrave},
-};
-/* Norwegian and Danish. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_E[] = {
- {'@', GDK_KEY_Adiaeresis},
- {'[', GDK_KEY_AE},
- {'\\', GDK_KEY_Ooblique},
- {']', GDK_KEY_Aring},
- {'^', GDK_KEY_Udiaeresis},
- {'`', GDK_KEY_adiaeresis},
- {'{', GDK_KEY_ae},
- {'|', GDK_KEY_oslash},
- {'}', GDK_KEY_aring},
- {'~', GDK_KEY_udiaeresis},
-};
-/* Spanish. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_Z[] = {
- {'#', GDK_KEY_sterling},
- {'@', GDK_KEY_section},
- {'[', GDK_KEY_exclamdown},
- {'\\', GDK_KEY_Ntilde},
- {']', GDK_KEY_questiondown},
- {'{', GDK_KEY_degree},
- {'|', GDK_KEY_ntilde},
- {'}', GDK_KEY_ccedilla},
-};
-/* Swedish. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_H[] = {
- {'@', GDK_KEY_Eacute},
- {'[', GDK_KEY_Adiaeresis},
- {'\\', GDK_KEY_Odiaeresis},
- {']', GDK_KEY_Aring},
- {'^', GDK_KEY_Udiaeresis},
- {'`', GDK_KEY_eacute},
- {'{', GDK_KEY_adiaeresis},
- {'|', GDK_KEY_odiaeresis},
- {'}', GDK_KEY_aring},
- {'~', GDK_KEY_udiaeresis},
-};
-/* Swiss. VT220 and higher (per XTerm docs). */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_equal[] = {
- {'#', GDK_KEY_ugrave},
- {'@', GDK_KEY_agrave},
- {'[', GDK_KEY_eacute},
- {'\\', GDK_KEY_ccedilla},
- {']', GDK_KEY_ecircumflex},
- {'^', GDK_KEY_icircumflex},
- {'_', GDK_KEY_egrave},
- {'`', GDK_KEY_ocircumflex},
- {'{', GDK_KEY_adiaeresis},
- {'|', GDK_KEY_odiaeresis},
- {'}', GDK_KEY_udiaeresis},
- {'~', GDK_KEY_ucircumflex},
-};
-/* Codepage 437. */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_U[] = {
-#include "unitable.CP437"
-};
-
-/* Japanese. JIS X 0201-1976 ("Roman" set), per RFC 1468/2237. */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_J[] = {
-#include "unitable.JIS0201"
-};
-/* Japanese. JIS X 0208-1978, per RFC 1468/2237. */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_wide_at[] = {
-#include "unitable.JIS0208"
-};
-/* Chinese. GB 2312-80, per RFC 1922. */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_wide_A[] = {
-#include "unitable.GB2312"
-};
-/* Japanese. JIS X 0208-1983, per RFC 1468/2237. */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_wide_B[] = {
-#include "unitable.JIS0208"
-};
-/* Korean. KS X 1001 (formerly KS C 5601), per Ken Lunde's
- * CJKV_Information_Processing. */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_wide_C[] = {
-#include "unitable.KSX1001"
-};
-/* Japanese. JIS X 0212-1990, per RFC 2237. */
-static const struct _vte_iso2022_map16 _vte_iso2022_map_wide_D[] = {
-#include "unitable.JIS0212"
-};
-/* Chinese. CNS 11643-plane-1, per RFC 1922. */
-static const struct _vte_iso2022_map32 _vte_iso2022_map_wide_G[] = {
-#include "unitable.CNS11643"
-};
-
-static gint
-_vte_direct_compare(gconstpointer a, gconstpointer b)
-{
- return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
-}
-
-/* If we have the encoding, decide how wide an ambiguously-wide character is
- * based on the encoding. This is basically what GNU libc does, and it agrees
- * with my reading of Unicode UAX 11, so.... */
-static int
-_vte_iso2022_ambiguous_width(struct _vte_iso2022_state *state)
-{
- const char wide_codelist[][10] = {
- "big5",
- "big5hkscs",
- "euccn",
- "eucjp",
- "euckr",
- "euctw",
- "gb18030",
- "gb2312",
- "gbk",
- "shiftjis",
- "tcvn",
- };
- gsize i, j;
- char codeset[16];
-
- /* Catch weirdo cases. */
- if ((state->codeset == NULL) || (state->codeset[0] == '\0')) {
- return 1;
- }
-
- /* Sort-of canonify the encoding name. */
- i = j = 0;
- for (i = 0; state->codeset[i] != '\0'; i++) {
- if (g_ascii_isalnum(state->codeset[i]))
- codeset[j++] = g_ascii_tolower(state->codeset[i]);
-
- if (j >= sizeof(codeset) - 1)
- break;
- }
- codeset[j] = '\0';
-
- /* Check for the name in the list. */
- for (i = 0; i < G_N_ELEMENTS(wide_codelist); i++) {
- if (strcmp(codeset, wide_codelist[i]) == 0) {
- return 2;
- }
- }
-
- /*
- * Decide the ambiguous width according to user preference if
- * current locale is UTF-8.
- */
- if (strcmp (codeset, "utf8") == 0) {
- return state->utf8_ambiguous_width;
- }
-
- /* Not in the list => not wide. */
- return 1;
-}
-
-static gboolean
-_vte_unichar_iswide_cjk(gunichar c)
-{
- /* U+254C..U+254F and U+2574..U+257F have East Asian Width property
- * N (neutral) while all the other line drawing characters are
- * A (ambigous). This makes those characters not match up with those
- * other line drawing characters from the Box Drawing (U+2500..U+257F)
- * block; so we treat them as ambigous too.
- *
- * And we also do the same for the Terminal Graphic Characters
- * (U+2596..U+259F) as well as U+2590 and U+2591 from the Block Elements
- * (U+2580..U+259F) block.
- */
- return G_UNLIKELY(c >= 0x2500 && c <= 0x259f);
-}
-
-static inline gboolean
-_vte_iso2022_is_ambiguous(gunichar c)
-{
- if (G_LIKELY (c < 0x80))
- return FALSE;
- if (G_UNLIKELY (g_unichar_iszerowidth (c)))
- return FALSE;
- return G_UNLIKELY (!g_unichar_iswide (c) && (g_unichar_iswide_cjk (c) || _vte_unichar_iswide_cjk
(c)));
-}
-
-int
-_vte_iso2022_unichar_width(struct _vte_iso2022_state *state,
- gunichar c)
-{
- if (G_LIKELY (c < 0x80))
- return 1;
- if (G_UNLIKELY (g_unichar_iszerowidth (c)))
- return 0;
- if (G_UNLIKELY (g_unichar_iswide (c)))
- return 2;
- if (G_LIKELY (state->ambiguous_width == 1))
- return 1;
- if (G_UNLIKELY (g_unichar_iswide_cjk (c)))
- return 2;
- return 1;
-}
-
-static GHashTable *
-_vte_iso2022_map_init16(const struct _vte_iso2022_map16 *map, gssize length)
-{
- GHashTable *ret;
- int i;
- if (length == 0) {
- return NULL;
- }
- ret = g_hash_table_new(NULL, NULL);
- for (i = 0; i < length; i++) {
- g_hash_table_insert(ret,
- GINT_TO_POINTER((unsigned int) map[i].from),
- GINT_TO_POINTER((unsigned int) map[i].to));
- }
- return ret;
-}
-
-static GHashTable *
-_vte_iso2022_map_init32(const struct _vte_iso2022_map32 *map, gssize length)
-{
- GHashTable *ret;
- int i;
- if (length == 0) {
- return NULL;
- }
- ret = g_hash_table_new(NULL, NULL);
- for (i = 0; i < length; i++) {
- g_hash_table_insert(ret,
- GINT_TO_POINTER((unsigned int) map[i].from),
- GINT_TO_POINTER((unsigned int) map[i].to));
- }
- return ret;
-}
-
-static void
-_vte_iso2022_map_get(gunichar mapname,
- GHashTable **_map, guint *bytes_per_char, guint *force_width,
- gulong *or_mask, gulong *and_mask)
-{
- static VteTree *maps = NULL;
- gint bytes = 0, width = 0;
- GHashTable *map = NULL;
- gboolean new_map = FALSE;
- gsize i;
-
- if (or_mask) {
- *or_mask = 0;
- }
- if (and_mask) {
- *and_mask = (~(0));
- }
-
- /* Make sure we have a map, erm, map. */
- if (maps == NULL) {
- maps = _vte_tree_new(_vte_direct_compare);
- }
-
- /* Check for a cached map for this charset. */
- map = _vte_tree_lookup(maps, GINT_TO_POINTER(mapname));
- new_map = map == NULL;
-
- /* Construct a new one. */
- switch (mapname) {
- case '0':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_0,
- G_N_ELEMENTS(_vte_iso2022_map_0));
- }
- width = 1;
- bytes = 1;
- break;
- case 'A':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_A,
- G_N_ELEMENTS(_vte_iso2022_map_A));
- }
- width = 1;
- bytes = 1;
- break;
- case '1': /* treated as an alias in xterm */
- case '2': /* treated as an alias in xterm */
- case 'B':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_B,
- G_N_ELEMENTS(_vte_iso2022_map_B));
- }
- width = 1;
- bytes = 1;
- break;
- case '4':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_4,
- G_N_ELEMENTS(_vte_iso2022_map_4));
- }
- width = 1;
- bytes = 1;
- break;
- case 'C':
- case '5':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_C,
- G_N_ELEMENTS(_vte_iso2022_map_C));
- }
- width = 1;
- bytes = 1;
- break;
- case 'R':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_R,
- G_N_ELEMENTS(_vte_iso2022_map_R));
- }
- width = 1;
- bytes = 1;
- break;
- case 'Q':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_Q,
- G_N_ELEMENTS(_vte_iso2022_map_Q));
- }
- width = 1;
- bytes = 1;
- break;
- case 'K':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_K,
- G_N_ELEMENTS(_vte_iso2022_map_K));
- }
- width = 1;
- bytes = 1;
- break;
- case 'Y':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_Y,
- G_N_ELEMENTS(_vte_iso2022_map_Y));
- }
- width = 1;
- bytes = 1;
- break;
- case 'E':
- case '6':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_E,
- G_N_ELEMENTS(_vte_iso2022_map_E));
- }
- width = 1;
- bytes = 1;
- break;
- case 'Z':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_Z,
- G_N_ELEMENTS(_vte_iso2022_map_Z));
- }
- width = 1;
- bytes = 1;
- break;
- case 'H':
- case '7':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_H,
- G_N_ELEMENTS(_vte_iso2022_map_H));
- }
- width = 1;
- bytes = 1;
- break;
- case '=':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_equal,
- G_N_ELEMENTS(_vte_iso2022_map_equal));
- }
- width = 1;
- bytes = 1;
- break;
- case 'U':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_U,
- G_N_ELEMENTS(_vte_iso2022_map_U));
- }
- width = 1;
- bytes = 1;
- break;
- case 'J':
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_J,
- G_N_ELEMENTS(_vte_iso2022_map_J));
- }
- width = 1;
- bytes = 1;
- break;
- case '@' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_wide_at,
- G_N_ELEMENTS(_vte_iso2022_map_wide_at));
- }
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- *and_mask = 0xf7f7f;
- break;
- case 'A' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_wide_A,
- G_N_ELEMENTS(_vte_iso2022_map_wide_A));
- }
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- *and_mask = 0xf7f7f;
- break;
- case 'B' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_wide_B,
- G_N_ELEMENTS(_vte_iso2022_map_wide_B));
- }
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- *and_mask = 0xf7f7f;
- break;
- case 'C' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_wide_C,
- G_N_ELEMENTS(_vte_iso2022_map_wide_C));
- }
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- *and_mask = 0xf7f7f;
- break;
- case 'D' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init16(_vte_iso2022_map_wide_D,
- G_N_ELEMENTS(_vte_iso2022_map_wide_D));
- }
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- *and_mask = 0xf7f7f;
- break;
- case 'G' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init32(_vte_iso2022_map_wide_G,
- G_N_ELEMENTS(_vte_iso2022_map_wide_G));
- }
- /* Return the plane number as part of the "or" mask. */
- g_assert(or_mask != NULL);
- *or_mask = 0x10000;
- *and_mask = 0xf7f7f;
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- break;
- case 'H' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init32(_vte_iso2022_map_wide_G,
- G_N_ELEMENTS(_vte_iso2022_map_wide_G));
- }
- /* Return the plane number as part of the "or" mask. */
- g_assert(or_mask != NULL);
- *or_mask = 0x20000;
- *and_mask = 0xf7f7f;
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- break;
- case 'I' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init32(_vte_iso2022_map_wide_G,
- G_N_ELEMENTS(_vte_iso2022_map_wide_G));
- }
- /* Return the plane number as part of the "or" mask. */
- g_assert(or_mask != NULL);
- *or_mask = 0x30000;
- *and_mask = 0xf7f7f;
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- break;
- case 'J' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init32(_vte_iso2022_map_wide_G,
- G_N_ELEMENTS(_vte_iso2022_map_wide_G));
- }
- /* Return the plane number as part of the "or" mask. */
- g_assert(or_mask != NULL);
- *or_mask = 0x40000;
- *and_mask = 0xf7f7f;
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- break;
- case 'K' + WIDE_FUDGE:
- if (map == NULL) {
- map = _vte_iso2022_map_init32(_vte_iso2022_map_wide_G,
- G_N_ELEMENTS(_vte_iso2022_map_wide_G));
- }
- /* Return the plane number as part of the "or" mask. */
- g_assert(or_mask != NULL);
- *or_mask = 0x50000;
- *and_mask = 0xf7f7f;
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- break;
- case 'L' + WIDE_FUDGE:
- if (G_UNLIKELY (map == NULL)) {
- map = _vte_iso2022_map_init32(_vte_iso2022_map_wide_G,
- G_N_ELEMENTS(_vte_iso2022_map_wide_G));
- }
- /* Return the plane number as part of the "or" mask. */
- g_assert(or_mask != NULL);
- *or_mask = 0x60000;
- *and_mask = 0xf7f7f;
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- break;
- case 'M' + WIDE_FUDGE:
- if (G_UNLIKELY(map == NULL)) {
- map = _vte_iso2022_map_init32(_vte_iso2022_map_wide_G,
- G_N_ELEMENTS(_vte_iso2022_map_wide_G));
- }
- /* Return the plane number as part of the "or" mask. */
- g_assert(or_mask != NULL);
- *or_mask = 0x70000;
- *and_mask = 0xf7f7f;
- width = 2; /* CJKV expects 2 bytes -> 2 columns */
- bytes = 2;
- break;
- default:
- /* No such map. Set up a ISO-8859-1 to UCS-4 map. */
- if (G_UNLIKELY (map == NULL)) {
- struct _vte_iso2022_map16 _vte_iso2022_map_NUL[256];
- for (i = 0; i < G_N_ELEMENTS(_vte_iso2022_map_NUL); i++) {
- _vte_iso2022_map_NUL[i].from = (i & 0xff);
- _vte_iso2022_map_NUL[i].to = (i & 0xff);
- }
- map = _vte_iso2022_map_init16(_vte_iso2022_map_NUL,
- G_N_ELEMENTS(_vte_iso2022_map_NUL));
- }
- width = 1;
- bytes = 1;
- break;
- }
- /* Save the new map. */
- if (G_UNLIKELY(new_map && map != NULL)) {
- _vte_tree_insert(maps, GINT_TO_POINTER(mapname), map);
- }
- /* Return. */
- if (_map) {
- *_map = map;
- }
- if (bytes_per_char) {
- *bytes_per_char = bytes;
- }
- if (force_width) {
- *force_width = width;
- }
-}
-
-int
-_vte_iso2022_get_encoded_width(gunichar c)
-{
- int width;
- width = (c & VTE_ISO2022_ENCODED_WIDTH_MASK) >> VTE_ISO2022_ENCODED_WIDTH_BIT_OFFSET;
- return CLAMP(width, 0, 2);
-}
-
-static gunichar
-_vte_iso2022_set_encoded_width(gunichar c, int width)
-{
- width = CLAMP(width, 0, 2);
- c &= ~(VTE_ISO2022_ENCODED_WIDTH_MASK);
- c |= (width << VTE_ISO2022_ENCODED_WIDTH_BIT_OFFSET);
- return c;
-}
-
struct _vte_iso2022_state *
-_vte_iso2022_state_new(const char *native_codeset,
- int utf8_ambiguous_width,
- _vte_iso2022_codeset_changed_cb_fn fn,
- gpointer data)
+_vte_iso2022_state_new(const char *native_codeset)
{
struct _vte_iso2022_state *state;
- g_return_val_if_fail(utf8_ambiguous_width == 1 || utf8_ambiguous_width == 2, NULL);
-
state = g_slice_new0(struct _vte_iso2022_state);
- state->nrc_enabled = TRUE;
- state->current = 0;
- state->override = -1;
- state->g[0] = 'B';
- state->g[1] = 'B';
- state->g[2] = 'B';
- state->g[3] = 'B';
state->native_codeset = state->codeset = g_intern_string(native_codeset);
if (native_codeset == NULL) {
const char *codeset;
@@ -784,8 +68,6 @@ _vte_iso2022_state_new(const char *native_codeset,
"Native codeset \"%s\", currently %s\n",
state->native_codeset, state->codeset);
state->conv = _vte_conv_open(state->target_codeset, state->codeset);
- state->codeset_changed = fn;
- state->codeset_changed_data = data;
state->buffer = _vte_byte_array_new();
if (state->conv == VTE_INVALID_CONV) {
g_warning(_("Unable to convert characters from %s to %s."),
@@ -800,7 +82,6 @@ _vte_iso2022_state_new(const char *native_codeset,
state->codeset, state->target_codeset);
}
}
- _vte_iso2022_state_set_utf8_ambiguous_width(state, utf8_ambiguous_width);
return state;
}
@@ -836,8 +117,6 @@ _vte_iso2022_state_set_codeset(struct _vte_iso2022_state *state,
}
state->codeset = g_intern_string (codeset);
state->conv = conv;
- state->ambiguous_width = _vte_iso2022_ambiguous_width (state);
-
}
const char *
@@ -846,348 +125,20 @@ _vte_iso2022_state_get_codeset(struct _vte_iso2022_state *state)
return state->codeset;
}
-void
-_vte_iso2022_state_set_utf8_ambiguous_width(struct _vte_iso2022_state *state,
- int utf8_ambiguous_width)
-{
- state->utf8_ambiguous_width = utf8_ambiguous_width;
- state->ambiguous_width = _vte_iso2022_ambiguous_width(state);
-}
-
-static const guchar *
-_vte_iso2022_find_nextctl(const guchar *p, const guchar * const q)
-{
- do {
- switch (*p) {
- case '\033':
- case '\n':
- case '\r':
- case '\016':
- case '\017':
-#ifdef VTE_ISO2022_8_BIT_CONTROLS
- /* This breaks UTF-8 and other encodings which
- * use the high bits.
- */
- case '0x8e':
- case '0x8f':
-#endif
- return p;
- }
- } while (++p < q);
- return NULL;
-}
-
-static long
-_vte_iso2022_sequence_length(const unsigned char *nextctl, gsize length)
-{
- long sequence_length = -1;
- gsize i;
-
- switch (nextctl[0]) {
- case '\n':
- case '\r':
- case '\016':
- case '\017':
- /* LF */
- /* CR */
- /* SO */
- /* SI */
- sequence_length = 1;
- break;
- case 0x8e:
- case 0x8f:
- /* SS2 - 8bit */
- /* SS3 - 8bit */
- sequence_length = 1;
- break;
- case '\033':
- if (length < 2) {
- /* Inconclusive. */
- sequence_length = 0;
- } else {
- switch (nextctl[1]) {
- case '[':
- /* ESC [, the CSI. The first letter
- * is the end of the sequence, */
- for (i = 2; i < length; i++) {
- if (g_unichar_isalpha(nextctl[i])) {
- break;
- }
- if ((nextctl[i] == '@') ||
- (nextctl[i] == '`') ||
- (nextctl[i] == '{') ||
- (nextctl[i] == '|')) {
- break;
- }
- }
- if (i < length) {
- /* Return the length of this
- * sequence. */
- sequence_length = i + 1;
- } else {
- /* Inconclusive. */
- sequence_length = 0;
- }
- break;
-#if 0
- case ']':
- /* ESC ], the OSC. Search for a string
- * terminator or a BEL. */
- for (i = 2; i < q - nextctl - 1; i++) {
- if ((nextctl[i] == '\033') &&
- (nextctl[i + 1] == '\\')) {
- break;
- }
- }
- if (i < length - 1) {
- /* Return the length of this
- * sequence. */
- sequence_length = i + 1;
- } else {
- for (i = 2; i < length; i++) {
- if (nextctl[i] == '\007') {
- break;
- }
- }
- if (i < length) {
- /* Return the length of
- * this sequence. */
- sequence_length = i + 1;
- } else {
- /* Inconclusive. */
- sequence_length = 0;
- }
- }
- break;
-#endif
-#if 0
- case '^':
- /* ESC ^, the PM. Search for a string
- * terminator. */
-#endif
- case 'P':
- /* ESC P, the DCS. Search for a string
- * terminator. */
- for (i = 2; i < length - 1; i++) {
- if ((nextctl[i] == '\033') &&
- (nextctl[i + 1] == '\\')) {
- break;
- }
- }
- if (i < length - 1) {
- /* Return the length of this
- * sequence. */
- sequence_length = i + 1;
- } else {
- /* Inconclusive. */
- sequence_length = 0;
- }
- break;
- case 'N':
- case 'O':
- case 'n':
- case 'o':
- /* ESC N */
- /* ESC O */
- /* ESC n */
- /* ESC o */
- sequence_length = 2;
- break;
- case '(':
- case ')':
- case '*':
- case '+':
- if (length < 3) {
- /* Inconclusive. */
- sequence_length = 0;
- } else {
- /* ESC ) x */
- /* ESC ( x */
- /* ESC * x */
- /* ESC + x */
- /* Just accept whatever. */
- sequence_length = 3;
- }
- break;
- case '%':
- if (length < 3) {
- /* Inconclusive. */
- sequence_length = 0;
- } else {
- /* ESC % @ */
- /* ESC % G */
- switch (nextctl[2]) {
- case '@':
- case 'G':
- sequence_length = 3;
- break;
- default:
- break;
- }
- }
- break;
- case '$':
- if (length < 3) {
- /* Inconclusive. */
- sequence_length = 0;
- } else {
- switch (nextctl[2]) {
- case '@':
- case 'B':
- /* ESC $ @ */
- /* ESC $ B */
- sequence_length = 3;
- break;
- case '(':
- case ')':
- case '*':
- case '+':
- /* ESC $ ( x */
- /* ESC $ ) x */
- /* ESC $ * x */
- /* ESC $ + x */
- if (length < 4) {
- /* Inconclusive. */
- sequence_length = 0;
- } else {
- /* strchr(WIDE_GMAPS, nextctl[3]) */
- switch (nextctl[3]) {
- case 'C':
- case 'A':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'D':
- sequence_length = 4;
- break;
- default:
- break;
- }
- }
- break;
- }
- }
- break;
- default:
- break;
- }
- }
- break;
- }
- return sequence_length;
-}
-
-static int
-process_8_bit_sequence(struct _vte_iso2022_state *state,
- const guchar **inbuf, gsize *inbytes,
- gunichar **outbuf, gsize *outbytes)
-{
- guint i, width;
- gpointer p;
- gunichar c, *outptr;
- const guchar *inptr;
- gulong acc, or_mask, and_mask;
- GHashTable *map;
- guint bytes_per_char, force_width, current;
-
- /* Check if it's an 8-bit escape. If it is, take a note of which map
- * it's for, and if it isn't, fail. */
- current = 0;
- switch (**inbuf) {
- case 0x8e:
- current = 2;
- break;
- case 0x8f:
- current = 3;
- break;
- default:
- /* We processed 0 bytes, and we have no intention of looking
- * at this byte again. */
- return 0;
- }
-
- inptr = *inbuf;
- outptr = *outbuf;
-
- /* Find the map, and ensure that in addition to the escape byte, we
- * have enough information to construct the character. */
- _vte_iso2022_map_get(state->g[current],
- &map, &bytes_per_char, &force_width,
- &or_mask, &and_mask);
- if (*inbytes < (bytes_per_char + 1)) {
- /* We need more information to work with. */
- return -1;
- }
-
- for (acc = 0, i = 0; i < bytes_per_char; i++) {
- acc = (acc << 8) | ((guint8*)inptr)[i + 1];
- }
- *inbuf += (bytes_per_char + 1);
- *inbytes -= (bytes_per_char + 1);
-
- acc &= and_mask;
- acc |= or_mask;
- p = GINT_TO_POINTER(acc);
- c = GPOINTER_TO_INT(g_hash_table_lookup(map, p));
- if ((c == 0) && (acc != 0)) {
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "%04lx -(%c)-> %04lx(?)\n",
- acc, state->g[current] & 0xff, acc);
- } else {
- width = 0;
- if (force_width != 0) {
- width = force_width;
- } else {
- if (G_UNLIKELY (_vte_iso2022_is_ambiguous(c))) {
- width = state->ambiguous_width;
- }
- }
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "%05lx -> " "%04x\n", acc, c);
- c = _vte_iso2022_set_encoded_width(c, width);
- }
- /* Save the unichar. */
- g_assert(*outbytes >= sizeof(c));
- *outbytes -= sizeof(c);
- *outptr++ = c;
- *outbuf = outptr;
- /* Return the number of input bytes consumed. */
- return bytes_per_char + 1;
-}
-
-static glong
-process_cdata(struct _vte_iso2022_state *state, const guchar *cdata, gsize length,
- gboolean incomplete_is_invalid, GArray *gunichars)
+gsize
+_vte_iso2022_process(struct _vte_iso2022_state *state,
+ const guchar *cdata, gsize length,
+ GArray *gunichars)
{
- int ambiguous_width;
glong processed = 0;
- GHashTable *map;
- guint bytes_per_char, force_width, current;
gsize converted;
const guchar *inbuf;
gunichar *outbuf, *buf;
gsize inbytes, outbytes;
- guint i, j, width;
- gulong acc, or_mask, and_mask;
+ guint i, j;
gunichar c;
- gboolean single, stop;
-
- ambiguous_width = state->ambiguous_width;
-
- single = (state->override != -1);
- current = single ? state->override : state->current;
- state->override = -1;
- g_assert(current < G_N_ELEMENTS(state->g));
+ gboolean stop;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "Current map = %d (%c).\n",
- current, (state->g[current] & 0xff));
-
- if (!state->nrc_enabled || (state->g[current] == 'B')) {
inbuf = cdata;
inbytes = length;
_vte_byte_array_set_minimum_size(state->buffer,
@@ -1202,41 +153,13 @@ process_cdata(struct _vte_iso2022_state *state, const guchar *cdata, gsize lengt
stop = FALSE;
switch (converted) {
case ((gsize)-1):
- if (errno == EINVAL && incomplete_is_invalid) {
- errno = EILSEQ;
- }
switch (errno) {
case EILSEQ:
- /* Check if it's an 8-bit sequence. */
- i = process_8_bit_sequence(state,
- &inbuf,
- &inbytes,
- &outbuf,
- &outbytes);
- switch (i) {
- case 0:
- /* iconv() may be buggy,
- * returning EILSEQ and
- * no remaining bytes.
- * Bug 567064 */
- if (inbytes) {
- /* Nope, munge the input. */
- inbuf++;
- inbytes--;
- }
- *outbuf++ = INVALID_CODEPOINT;
- outbytes -= sizeof(gunichar);
- break;
- case -1:
- /* Looks good so far, try again
- * later. */
- stop = TRUE;
- break;
- default:
- /* Processed n bytes, just keep
- * going. */
- break;
- }
+ /* Munge the input. */
+ inbuf++;
+ inbytes--;
+ *outbuf++ = INVALID_CODEPOINT;
+ outbytes -= sizeof(gunichar);
break;
case EINVAL:
/* Incomplete. Save for later. */
@@ -1256,7 +179,7 @@ process_cdata(struct _vte_iso2022_state *state, const guchar *cdata, gsize lengt
}
} while ((inbytes > 0) && !stop);
- /* encode any ambiguous widths and skip blanks */
+ /* skip blanks -- TODOegmont: why here? */
j = gunichars->len;
g_array_set_size(gunichars, gunichars->len + outbuf-buf);
for (i = 0; buf + i < outbuf; i++) {
@@ -1265,595 +188,14 @@ process_cdata(struct _vte_iso2022_state *state, const guchar *cdata, gsize lengt
/* Skip the padding character. */
continue;
}
- if (G_UNLIKELY (_vte_iso2022_is_ambiguous(c))) {
- width = ambiguous_width;
- c = _vte_iso2022_set_encoded_width(c, width);
- }
g_array_index(gunichars, gunichar, j++) = c;
}
gunichars->len = j;
/* Done. */
processed = length - inbytes;
- } else {
- _vte_iso2022_map_get(state->g[current],
- &map, &bytes_per_char, &force_width,
- &or_mask, &and_mask);
- i = 0;
- acc = 0;
- j = gunichars->len;
- g_array_set_size(gunichars, gunichars->len + length);
- do {
- if (i < length) {
- acc = (acc << 8) | cdata[i];
- }
- i++;
- if ((i % bytes_per_char) == 0) {
- acc &= and_mask;
- acc |= or_mask;
- c = GPOINTER_TO_INT(g_hash_table_lookup(map,
- GINT_TO_POINTER(acc)));
- if ((c == 0) && (acc != 0)) {
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "%04lx -(%c)-> "
- "%04lx(?)\n",
- acc,
- state->g[current] & 0xff,
- acc);
- c = acc;
- } else {
- width = 0;
- if (force_width != 0) {
- width = force_width;
- } else {
- if (G_UNLIKELY (_vte_iso2022_is_ambiguous(c))) {
- width = ambiguous_width;
- }
- }
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "%05lx -> "
- "%04x\n", acc, c);
- c = _vte_iso2022_set_encoded_width(c, width);
- }
- g_array_index(gunichars, gunichar, j++) = c;
- if (single) {
- break;
- }
- acc = 0;
- }
- } while (i < length);
- processed = i;
- gunichars->len = j;
- }
- return processed;
-}
-
-gunichar
-_vte_iso2022_process_single(struct _vte_iso2022_state *state,
- gunichar c, gunichar map)
-{
- GHashTable *hash;
- gunichar ret = c;
- gpointer p;
- guint bytes_per_char, force_width;
- gulong or_mask, and_mask;
-
- _vte_iso2022_map_get(map,
- &hash, &bytes_per_char, &force_width,
- &or_mask, &and_mask);
-
- p = GINT_TO_POINTER((c & and_mask) | or_mask);
- if (hash != NULL) {
- p = g_hash_table_lookup(hash, p);
- }
- if (p != NULL) {
- ret = GPOINTER_TO_INT(p);
- }
- if (force_width) {
- ret = _vte_iso2022_set_encoded_width(ret, force_width);
- }
- return ret;
-}
-static void
-process_control(struct _vte_iso2022_state *state, guchar *ctl, gsize length,
- GArray *gunichars)
-{
- gunichar c;
- gsize i;
- if (length >= 1) {
- switch (ctl[0]) {
- case '\r': /* CR */
- c = '\r';
- g_array_append_val(gunichars, c);
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION, "\tCR\n");
- break;
- case '\n': /* LF */
- c = '\n';
- g_array_append_val(gunichars, c);
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION, "\tLF\n");
- break;
- case '\016': /* SO */
- state->current = 1;
- state->override = -1;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION, "\tSO (^N)\n");
- break;
- case '\017': /* SI */
- state->current = 0;
- state->override = -1;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION, "\tSI (^O)\n");
- break;
- case 0x8e:
- /* SS2 - 8bit */
- state->override = 2;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tSS2 (8-bit)\n");
- break;
- case 0x8f:
- /* SS3 - 8bit */
- state->override = 3;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tSS3 (8-bit)\n");
- break;
- case '\033':
- if (length >= 2) {
- switch (ctl[1]) {
- case '[': /* CSI */
- case ']': /* OSC */
- case '^': /* PM */
- case 'P': /* DCS */
- /* Pass it through. */
- for (i = 0; i < length; i++) {
- c = (guchar) ctl[i];
- g_array_append_val(gunichars,
- c);
- }
- _VTE_DEBUG_IF(VTE_DEBUG_SUBSTITUTION) {
- g_printerr("\t");
- for (i = 0; i < length; i++) {
- c = (guchar) ctl[i];
- g_printerr(
- "(%s%c)",
- c < 0x20 ?
- "^" : "",
- c < 0x20 ?
- c : c + 64);
- }
- g_printerr("\n");
- }
- break;
- case 'N': /* SS2 */
- state->override = 2;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tSS2\n");
- break;
- case 'O': /* SS3 */
- state->override = 3;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tSS3\n");
- break;
- case 'n': /* LS2 */
- state->current = 2;
- state->override = -1;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tLS2\n");
- break;
- case 'o': /* LS3 */
- state->current = 3;
- state->override = -1;
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tLS3\n");
- break;
- case '(':
- case ')':
- case '*':
- case '+':
- if (length >= 3) {
- int g = -1;
- switch (ctl[1]) {
- case '(':
- g = 0;
- break;
- case ')':
- g = 1;
- break;
- case '*':
- g = 2;
- break;
- case '+':
- g = 3;
- break;
- default:
- g_assert_not_reached();
- break;
- }
- /* strchr(NARROW_MAPS, c) */
- switch (ctl[2]) {
- case '0':
- case '1':
- case '2':
- case 'A':
- case 'B':
- case '4':
- case 'C':
- case '5':
- case 'R':
- case 'Q':
- case 'K':
- case 'Y':
- case 'E':
- case '6':
- case 'Z':
- case 'H':
- case '7':
- case '=':
- case 'J':
- case 'U':
- state->g[g] = ctl[2];
- break;
-
- default:
- g_warning(_("Attempt to set invalid NRC map '%c'."),
ctl[2]);
- break;
- }
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tG[%d] = %c.\n",
- g, c);
- }
- break;
- case '%':
- if (length >= 3) {
- gboolean notify = FALSE;
- switch (ctl[2]) {
- case '@':
- if (strcmp(state->codeset, state->native_codeset) !=
0) {
- notify = TRUE;
- }
- _vte_iso2022_state_set_codeset(state,
state->native_codeset);
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tNative encoding.\n");
- break;
- case 'G':
- if (strcmp(state->codeset, state->utf8_codeset) != 0)
{
- notify = TRUE;
- }
- _vte_iso2022_state_set_codeset(state,
state->utf8_codeset);
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tUTF-8 encoding.\n");
- break;
- default:
- /* Application signalled an "identified coding
system" we haven't heard of. See ECMA-35 for gory details. */
- g_warning(_("Unrecognized identified coding
system."));
- break;
- }
- if (notify &&
- state->codeset_changed) {
- state->codeset_changed(state,
state->codeset_changed_data);
- }
- }
- break;
- case '$':
- if (length >= 4) {
- int g = -1;
- c = 0;
- switch (ctl[2]) {
- case '@':
- g = 0;
- c = '@';
- break;
- case 'B':
- g = 0;
- c = 'B';
- break;
- case '(':
- g = 0;
- break;
- case ')':
- g = 1;
- break;
- case '*':
- g = 2;
- break;
- case '+':
- g = 3;
- break;
- default:
- g_assert_not_reached();
- break;
- }
- if (c == 0) {
- c = ctl[3];
- }
- /* strchr(WIDE_MAPS WIDE_GMAPS, c) */
- switch (c) {
- case '@':
- case 'B':
- case 'C':
- case 'A':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'D':
- state->g[g] = c + WIDE_FUDGE;
- break;
-
- default:
- g_warning(_("Attempt to set invalid wide NRC map
'%c'."), c);
- break;
- }
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tG[%d] = wide %c.\n",
- g, c);
- } else
- if (length >= 3) {
- switch (ctl[2]) {
- case '@':
- c = '@';
- break;
- case 'B':
- c = 'B';
- break;
- default:
- c = ctl[2];
- break;
- }
- /* strchr(WIDE_MAPS, c) */
- switch (c){
- case '@':
- case 'B':
- state->g[0] = c + WIDE_FUDGE;
- break;
-
- default:
- g_warning(_("Attempt to set invalid wide NRC map
'%c'."), c);
- }
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "\tG[0] = wide %c.\n",
- c);
- }
- break;
- default:
- g_assert_not_reached();
- break;
- }
- break;
- }
- break;
- default:
- g_assert_not_reached();
- break;
- }
- }
-}
-
-static guint
-process_block (struct _vte_iso2022_state *state,
- guchar *input,
- struct _vte_iso2022_block *block,
- gboolean last,
- gboolean incomplete_is_invalid,
- GArray *gunichars)
-{
- guint preserve_last = -1;
- guint initial;
-
- switch (block->type) {
- case _vte_iso2022_cdata:
- _VTE_DEBUG_IF(VTE_DEBUG_SUBSTITUTION) {
- guint j;
- g_printerr("%3ld %3ld CDATA \"%.*s\"",
- block->start, block->end,
- (int) (block->end - block->start),
- input + block->start);
- g_printerr(" (");
- for (j = block->start; j < block->end; j++) {
- if (j > block->start) {
- g_printerr(", ");
- }
- g_printerr("0x%02x",
- input[j]);
- }
- g_printerr(")\n");
- }
- initial = 0;
- while (initial < block->end - block->start) {
- int j;
- j = process_cdata(state,
- input +
- block->start +
- initial,
- block->end -
- block->start -
- initial,
- incomplete_is_invalid,
- gunichars);
- if (j == 0) {
- break;
- }
- initial += j;
- }
- if (initial < block->end - block->start && last) {
- preserve_last = block->start + initial;
- }
- break;
- case _vte_iso2022_control:
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "%3ld %3ld CONTROL ",
- block->start, block->end);
- process_control(state,
- input + block->start,
- block->end - block->start,
- gunichars);
- break;
- case _vte_iso2022_preserve:
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "%3ld %3ld PRESERVE\n",
- block->start, block->end);
- preserve_last = block->start;
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
- return preserve_last;
-}
-
-gsize
-_vte_iso2022_process(struct _vte_iso2022_state *state,
- guchar *input, gsize length,
- GArray *gunichars)
-{
- struct _vte_iso2022_block block;
- guint preserve_last = -1;
- const guchar *nextctl, *p, *q;
- glong sequence_length = 0;
-
- p = input;
- q = input + length;
- do {
- nextctl = _vte_iso2022_find_nextctl(p, q);
- if (nextctl == NULL) {
- /* It's all garden-variety data. */
- block.type = _vte_iso2022_cdata;
- block.start = p - input;
- block.end = q - input;
- preserve_last = process_block (state,
- input, &block,
- TRUE,
- FALSE,
- gunichars);
- break;
- }
- /* We got some garden-variety data. */
- if (nextctl != p) {
- block.type = _vte_iso2022_cdata;
- block.start = p - input;
- block.end = nextctl - input;
- process_block (state, input, &block, FALSE, TRUE, gunichars);
- }
- /* Move on to the control data. */
- p = nextctl;
- sequence_length = _vte_iso2022_sequence_length(nextctl,
- q - nextctl);
- switch (sequence_length) {
- case -1:
- /* It's just garden-variety data. */
- block.type = _vte_iso2022_cdata;
- block.start = p - input;
- block.end = nextctl + 1 - input;
- /* Continue at the next byte. */
- p = nextctl + 1;
- break;
- case 0:
- /* Inconclusive. Save this data and try again later. */
- block.type = _vte_iso2022_preserve;
- block.start = nextctl - input;
- block.end = q - input;
- /* Trigger an end-of-loop. */
- p = q;
- break;
- default:
- /* It's a control sequence. */
- block.type = _vte_iso2022_control;
- block.start = nextctl - input;
- block.end = nextctl + sequence_length - input;
- /* Continue after the sequence. */
- p = nextctl + sequence_length;
- break;
- }
- preserve_last = process_block (state,
- input, &block,
- FALSE,
- FALSE,
- gunichars);
- } while (p < q);
- if (preserve_last != (guint) -1) {
- length = preserve_last;
- }
_vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "Consuming %ld bytes.\n", (long) length);
- return length;
-}
-
-#ifdef ISO2022_MAIN
-#include <stdio.h>
-int
-main(int argc, char **argv)
-{
- VteByteArray *buffer;
- struct _vte_iso2022_state *state;
- GString *string;
- GArray *gunichars;
- struct {
- const char *s;
- gboolean process;
- } strings[] = {
- {"abcd\033$(Cefgh\ri\nj\033)0k\017lmn\033Nopqrst\033%G", TRUE},
- {"ABCD\033$(C\033)", TRUE},
- {"0", TRUE},
- {"\014\033[33;41m", TRUE},
- {"\015", TRUE},
- {"\014{|}\015\r\n", TRUE},
- {"\033(B\033)0\033*B\033+B", TRUE},
- {"\033$B$+$J4A;z\033(J~", TRUE},
- {"\033(B\033)0\033*B\033+B", TRUE},
- {"\033$)C\0161hD!\017", TRUE},
- {"\033$*C\033N1hD!", TRUE},
- {"\033$(G\043\071", TRUE},
- {"\033(B\033)0\033*B\033+B", TRUE},
- {"\r\n", TRUE},
- };
- guint i;
- FILE *fp;
- guchar b;
-
- state = _vte_iso2022_state_new(NULL, VTE_ISO2022_DEFAULT_UTF8_AMBIGUOUS_WIDTH, NULL, NULL);
- buffer = _vte_byte_array_new();
- gunichars = g_array_new(FALSE, FALSE, sizeof(gunichar));
- if (argc > 1) {
- string = g_string_new(NULL);
- for (i = 1; i < (guint) argc; i++) {
- if (strcmp(argv[i], "-") == 0) {
- fp = stdin;
- } else {
- fp = fopen(argv[i], "r");
- }
- while (fread(&b, sizeof(guchar), 1, fp) == sizeof(b)) {
- g_string_append_c(string, b);
- }
- if (fp != stdin) {
- fclose(fp);
- }
- }
- _vte_byte_array_append(buffer, string->str, string->len);
- _vte_iso2022_process(state, buffer->data, _vte_byte_array_length (buffer), gunichars);
- g_string_free(string, TRUE);
- } else {
- for (i = 0; i < G_N_ELEMENTS(strings); i++) {
- string = g_string_new(strings[i].s);
- _vte_byte_array_append(buffer, string->str, string->len);
- g_string_free(string, TRUE);
- if (strings[i].process) {
- _vte_iso2022_process(state, buffer->data, _vte_byte_array_length (buffer),
gunichars);
- }
- }
- }
- _vte_byte_array_free(buffer);
- _vte_iso2022_state_free(state);
-
- string = g_string_new(NULL);
- for (i = 0; i < gunichars->len; i++) {
- g_string_append_unichar(string,
- g_array_index(gunichars, gunichar, i));
- }
- (void) write(STDOUT_FILENO, string->str, string->len);
- g_string_free(string, TRUE);
-
- return 0;
+ "Consuming %ld bytes.\n", (long) processed);
+ return processed;
}
-#endif
diff --git a/src/iso2022.h b/src/iso2022.h
index 0c186e7..4e417c2 100644
--- a/src/iso2022.h
+++ b/src/iso2022.h
@@ -30,33 +30,15 @@
G_BEGIN_DECLS
struct _vte_iso2022_state;
-typedef void (*_vte_iso2022_codeset_changed_cb_fn)(struct _vte_iso2022_state *,
- gpointer);
-struct _vte_iso2022_state *_vte_iso2022_state_new(const char *native_codeset,
- int utf8_ambiguous_width,
- _vte_iso2022_codeset_changed_cb_fn,
- gpointer);
+struct _vte_iso2022_state *_vte_iso2022_state_new(const char *native_codeset);
void _vte_iso2022_state_set_codeset(struct _vte_iso2022_state *state,
const char *codeset);
-void _vte_iso2022_state_set_utf8_ambiguous_width(struct _vte_iso2022_state *state,
- int utf8_ambiguous_width);
const char *_vte_iso2022_state_get_codeset(struct _vte_iso2022_state *state);
gsize _vte_iso2022_process(struct _vte_iso2022_state *state,
- guchar *input, gsize length,
+ const guchar *input, gsize length,
GArray *gunichars);
-gunichar _vte_iso2022_process_single(struct _vte_iso2022_state *state,
- gunichar c, gunichar map);
void _vte_iso2022_state_free(struct _vte_iso2022_state *);
-#define VTE_ISO2022_DEFAULT_UTF8_AMBIGUOUS_WIDTH 1
-
-#define VTE_ISO2022_ENCODED_WIDTH_BIT_OFFSET 28
-#define VTE_ISO2022_ENCODED_WIDTH_MASK (3 << VTE_ISO2022_ENCODED_WIDTH_BIT_OFFSET)
-#define VTE_ISO2022_HAS_ENCODED_WIDTH(__c) (((__c) & VTE_ISO2022_ENCODED_WIDTH_MASK) != 0)
-int _vte_iso2022_get_encoded_width(gunichar c);
-int _vte_iso2022_unichar_width(struct _vte_iso2022_state *state,
- gunichar c);
-
G_END_DECLS
#endif
diff --git a/src/table.c b/src/table.c
index e8d1cf6..820b00c 100644
--- a/src/table.c
+++ b/src/table.c
@@ -561,13 +561,10 @@ _vte_table_extract_string(GValueArray **array,
{
GValue value = {0,};
gunichar *ptr;
- guint i;
ptr = g_new(gunichar, arginfo->length + 1);
- for (i = 0; i < arginfo->length; i++) {
- ptr[i] = arginfo->start[i] & ~VTE_ISO2022_ENCODED_WIDTH_MASK;
- }
- ptr[i] = '\0';
+ memcpy(ptr, arginfo->start, sizeof(gunichar) * arginfo->length);
+ ptr[arginfo->length] = '\0';
g_value_init(&value, G_TYPE_POINTER);
g_value_set_pointer(&value, ptr);
diff --git a/src/vte-private.h b/src/vte-private.h
index ca10c2e..77de804 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -108,6 +108,7 @@ G_BEGIN_DECLS
#define VTE_UPDATE_REPEAT_TIMEOUT 30
#define VTE_MAX_PROCESS_TIME 100
#define VTE_CELL_BBOX_SLACK 1
+#define VTE_DEFAULT_UTF8_AMBIGUOUS_WIDTH 1
#define VTE_UTF8_BPC (6) /* Maximum number of bytes used per UTF-8 character */
@@ -149,6 +150,12 @@ struct vte_match_regex {
} cursor;
};
+typedef enum _VteCharacterReplacement {
+ VTE_CHARACTER_REPLACEMENT_NONE,
+ VTE_CHARACTER_REPLACEMENT_LINE_DRAWING,
+ 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 {
@@ -213,7 +220,7 @@ struct _VteTerminalPrivate {
/* Input data queues. */
const char *encoding; /* the pty's encoding */
- int iso2022_utf8_ambiguous_width;
+ int utf8_ambiguous_width;
struct _vte_iso2022_state *iso2022;
struct _vte_incoming_chunk{
struct _vte_incoming_chunk *next;
@@ -265,7 +272,6 @@ struct _VteTerminalPrivate {
plus the current
fore/back with no
character data */
- gboolean alternate_charset;
} normal_screen, alternate_screen, *screen;
/* Selection information. */
@@ -293,7 +299,6 @@ struct _VteTerminalPrivate {
gboolean margin_bell;
guint bell_margin;
gboolean allow_bold;
- gboolean nrc_mode;
gboolean deccolm_mode; /* DECCOLM allowed */
GHashTable *tabstops;
gboolean text_modified_flag;
@@ -301,6 +306,8 @@ struct _VteTerminalPrivate {
gboolean text_deleted_flag;
gboolean rewrap_on_resize;
gboolean bracketed_paste_mode;
+ VteCharacterReplacement character_replacements[2]; /* charsets in the G0 and G1 slots */
+ VteCharacterReplacement *character_replacement; /* pointer to the active one */
/* Scrolling options. */
gboolean scroll_background;
diff --git a/src/vte.c b/src/vte.c
index a018cd1..2154b36 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -84,6 +84,7 @@ typedef gunichar wint_t;
#define WORD_CHAR_ASCII_PUNCT "-,.;/?%&#_=+ ~"
+static int _vte_unichar_width(gunichar c, int utf8_ambiguous_width);
static void vte_terminal_set_visibility (VteTerminal *terminal, GdkVisibilityState state);
static void vte_terminal_paste(VteTerminal *terminal, GdkAtom board);
static void vte_terminal_real_copy_clipboard(VteTerminal *terminal);
@@ -187,6 +188,22 @@ static GTimer *process_timer;
static const GtkBorder default_padding = { 1, 1, 1, 1 };
+static int
+_vte_unichar_width(gunichar c, int utf8_ambiguous_width)
+{
+ if (G_LIKELY (c < 0x80))
+ return 1;
+ if (G_UNLIKELY (g_unichar_iszerowidth (c)))
+ return 0;
+ if (G_UNLIKELY (g_unichar_iswide (c)))
+ return 2;
+ if (G_LIKELY (utf8_ambiguous_width == 1))
+ return 1;
+ if (G_UNLIKELY (g_unichar_iswide_cjk (c)))
+ return 2;
+ return 1;
+}
+
/* process incoming data without copying */
static struct _vte_incoming_chunk *free_chunks;
static struct _vte_incoming_chunk *
@@ -620,7 +637,7 @@ vte_terminal_preedit_width(VteTerminal *terminal, gboolean left_only)
(!left_only || (i < terminal->pvt->im_preedit_cursor));
i++) {
c = g_utf8_get_char(preedit);
- ret += _vte_iso2022_unichar_width(terminal->pvt->iso2022, c);
+ ret += _vte_unichar_width(c, terminal->pvt->utf8_ambiguous_width);
preedit = g_utf8_next_char(preedit);
}
}
@@ -2070,9 +2087,6 @@ vte_terminal_get_encoding(VteTerminal *terminal)
* This setting controls whether ambiguous-width characters are narrow or wide
* when using the UTF-8 encoding (vte_terminal_set_encoding()). In all other encodings,
* the width of ambiguous-width characters is fixed.
- *
- * This setting only takes effect the next time the terminal is reset, either
- * via escape sequence or with vte_terminal_reset().
*/
void
vte_terminal_set_cjk_ambiguous_width(VteTerminal *terminal, int width)
@@ -2080,9 +2094,7 @@ vte_terminal_set_cjk_ambiguous_width(VteTerminal *terminal, int width)
g_return_if_fail(VTE_IS_TERMINAL(terminal));
g_return_if_fail(width == 1 || width == 2);
- terminal->pvt->iso2022_utf8_ambiguous_width = width;
- if (terminal->pvt->pty == NULL)
- _vte_iso2022_state_set_utf8_ambiguous_width(terminal->pvt->iso2022, width);
+ terminal->pvt->utf8_ambiguous_width = width;
}
/**
@@ -2098,7 +2110,7 @@ int
vte_terminal_get_cjk_ambiguous_width(VteTerminal *terminal)
{
g_return_val_if_fail(VTE_IS_TERMINAL(terminal), 1);
- return terminal->pvt->iso2022_utf8_ambiguous_width;
+ return terminal->pvt->utf8_ambiguous_width;
}
static inline VteRowData *
@@ -3031,28 +3043,57 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
VteScreen *screen;
gboolean line_wrapped = FALSE; /* cursor moved before char inserted */
+ /* DEC Special Character and Line Drawing Set. VT100 and higher (per XTerm docs). */
+ static gunichar line_drawing_map[31] = {
+ 0x25c6, /* ` => diamond */
+ 0x2592, /* a => checkerboard */
+ 0x2409, /* b => HT symbol */
+ 0x240c, /* c => FF symbol */
+ 0x240d, /* d => CR symbol */
+ 0x240a, /* e => LF symbol */
+ 0x00b0, /* f => degree */
+ 0x00b1, /* g => plus/minus */
+ 0x2424, /* h => NL symbol */
+ 0x240b, /* i => VT symbol */
+ 0x2518, /* j => downright corner */
+ 0x2510, /* k => upright corner */
+ 0x250c, /* l => upleft corner */
+ 0x2514, /* m => downleft corner */
+ 0x253c, /* n => cross */
+ 0x23ba, /* o => scan line 1/9 */
+ 0x23bb, /* p => scan line 3/9 */
+ 0x2500, /* q => horizontal line (also scan line 5/9) */
+ 0x23bc, /* r => scan line 7/9 */
+ 0x23bd, /* s => scan line 9/9 */
+ 0x251c, /* t => left t */
+ 0x2524, /* u => right t */
+ 0x2534, /* v => bottom t */
+ 0x252c, /* w => top t */
+ 0x2502, /* x => vertical line */
+ 0x2264, /* y => <= */
+ 0x2265, /* z => >= */
+ 0x03c0, /* { => pi */
+ 0x2260, /* | => not equal */
+ 0x00a3, /* } => pound currency sign */
+ 0x00b7, /* ~ => bullet */
+ };
+
screen = terminal->pvt->screen;
insert |= screen->insert_mode;
invalidate_now |= insert;
/* If we've enabled the special drawing set, map the characters to
* Unicode. */
- if (G_UNLIKELY (screen->alternate_charset)) {
- _vte_debug_print(VTE_DEBUG_SUBSTITUTION,
- "Attempting charset substitution"
- "for U+%04X.\n", c);
- /* See if there's a mapping for it. */
- c = _vte_iso2022_process_single(terminal->pvt->iso2022, c, '0');
- }
+ if (G_UNLIKELY (*terminal->pvt->character_replacement == VTE_CHARACTER_REPLACEMENT_LINE_DRAWING)) {
+ if (c >= 96 && c <= 126)
+ c = line_drawing_map[c - 96];
+ } else if (G_UNLIKELY (*terminal->pvt->character_replacement == VTE_CHARACTER_REPLACEMENT_BRITISH)) {
+ if (G_UNLIKELY (c == '#'))
+ c = 0x00a3; /* pound sign */
+ }
/* Figure out how many columns this character should occupy. */
- if (G_UNLIKELY (VTE_ISO2022_HAS_ENCODED_WIDTH(c))) {
- columns = _vte_iso2022_get_encoded_width(c);
- c &= ~VTE_ISO2022_ENCODED_WIDTH_MASK;
- } else {
- columns = _vte_iso2022_unichar_width(terminal->pvt->iso2022, c);
- }
-
+ columns = _vte_unichar_width(c, terminal->pvt->utf8_ambiguous_width);
/* If we're autowrapping here, do it. */
col = screen->cursor_current.col;
@@ -3797,20 +3838,19 @@ skip_chunk:
}
}
_VTE_DEBUG_IF(VTE_DEBUG_PARSE) {
- gunichar cc = c & ~VTE_ISO2022_ENCODED_WIDTH_MASK;
- if (cc > 255) {
- g_printerr("U+%04lx\n", (long) cc);
+ if (c > 255) {
+ g_printerr("U+%04lx\n", (long) c);
} else {
- if (cc > 127) {
+ if (c > 127) {
g_printerr("%ld = ",
- (long) cc);
+ (long) c);
}
- if (cc < 32) {
+ if (c < 32) {
g_printerr("^%lc\n",
- (wint_t)cc + 64);
+ (wint_t)c + 64);
} else {
g_printerr("`%lc'\n",
- (wint_t)cc);
+ (wint_t)c);
}
}
}
@@ -7905,12 +7945,6 @@ _vte_terminal_inline_error_message(VteTerminal *terminal, const char *format, ..
g_free (str);
}
-static void
-_vte_terminal_codeset_changed_cb(struct _vte_iso2022_state *state, gpointer p)
-{
- vte_terminal_set_encoding(p, _vte_iso2022_state_get_codeset(state), NULL);
-}
-
/* Initialize the terminal widget after the base widget stuff is initialized.
* We need to create a new psuedo-terminal pair, and set ourselves up to do
* the interpretation of sequences. */
@@ -7965,17 +7999,19 @@ vte_terminal_init(VteTerminal *terminal)
pvt->screen = &terminal->pvt->normal_screen;
_vte_terminal_set_default_attributes(terminal);
+ /* Initialize charset modes. */
+ pvt->character_replacements[0] = VTE_CHARACTER_REPLACEMENT_NONE;
+ pvt->character_replacements[1] = VTE_CHARACTER_REPLACEMENT_NONE;
+ pvt->character_replacement = &pvt->character_replacements[0];
+
/* Set up the desired palette. */
vte_terminal_set_default_colors(terminal);
for (i = 0; i < VTE_PALETTE_SIZE; i++)
terminal->pvt->palette[i].sources[VTE_COLOR_SOURCE_ESCAPE].is_set = FALSE;
/* Set up I/O encodings. */
- pvt->iso2022_utf8_ambiguous_width = VTE_ISO2022_DEFAULT_UTF8_AMBIGUOUS_WIDTH;
- pvt->iso2022 = _vte_iso2022_state_new(pvt->encoding,
- pvt->iso2022_utf8_ambiguous_width,
- &_vte_terminal_codeset_changed_cb,
- terminal);
+ pvt->utf8_ambiguous_width = VTE_DEFAULT_UTF8_AMBIGUOUS_WIDTH;
+ pvt->iso2022 = _vte_iso2022_state_new(pvt->encoding);
pvt->incoming = NULL;
pvt->pending = g_array_new(FALSE, TRUE, sizeof(gunichar));
pvt->max_input_bytes = VTE_MAX_INPUT_READ;
@@ -8014,7 +8050,6 @@ vte_terminal_init(VteTerminal *terminal)
pvt->audible_bell = TRUE;
pvt->bell_margin = 10;
pvt->allow_bold = TRUE;
- pvt->nrc_mode = TRUE;
pvt->deccolm_mode = FALSE;
pvt->rewrap_on_resize = TRUE;
vte_terminal_set_default_tabstops(terminal);
@@ -9676,8 +9711,8 @@ vte_terminal_paint_im_preedit_string(VteTerminal *terminal)
items = g_new(struct _vte_draw_text_request, len);
for (i = columns = 0; i < len; i++) {
items[i].c = g_utf8_get_char(preedit);
- items[i].columns = _vte_iso2022_unichar_width(terminal->pvt->iso2022,
- items[i].c);
+ items[i].columns = _vte_unichar_width(items[i].c,
+ terminal->pvt->utf8_ambiguous_width);
items[i].x = (col + columns) * width;
items[i].y = row * height;
columns += items[i].columns;
@@ -10771,7 +10806,7 @@ vte_terminal_class_init(VteTerminalClass *klass)
(gobject_class,
PROP_CJK_AMBIGUOUS_WIDTH,
g_param_spec_int ("cjk-ambiguous-width", NULL, NULL,
- 1, 2, VTE_ISO2022_DEFAULT_UTF8_AMBIGUOUS_WIDTH,
+ 1, 2, VTE_DEFAULT_UTF8_AMBIGUOUS_WIDTH,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
/**
@@ -11733,10 +11768,7 @@ vte_terminal_reset(VteTerminal *terminal,
_vte_byte_array_clear(pvt->outgoing);
/* Reset charset substitution state. */
_vte_iso2022_state_free(pvt->iso2022);
- pvt->iso2022 = _vte_iso2022_state_new(NULL,
- pvt->iso2022_utf8_ambiguous_width,
- &_vte_terminal_codeset_changed_cb,
- terminal);
+ pvt->iso2022 = _vte_iso2022_state_new(NULL);
_vte_iso2022_state_set_codeset(pvt->iso2022,
pvt->encoding);
/* Reset keypad/cursor key modes. */
@@ -11748,8 +11780,6 @@ vte_terminal_reset(VteTerminal *terminal,
pvt->meta_sends_escape = TRUE;
/* Disable margin bell. */
pvt->margin_bell = FALSE;
- /* Enable iso2022/NRC processing. */
- pvt->nrc_mode = TRUE;
/* Disable DECCOLM mode. */
pvt->deccolm_mode = FALSE;
/* Reset saved settings. */
@@ -11766,9 +11796,10 @@ vte_terminal_reset(VteTerminal *terminal,
_vte_terminal_set_default_attributes(terminal);
pvt->screen = &pvt->normal_screen;
_vte_terminal_set_default_attributes(terminal);
- /* Reset alternate charset mode. */
- pvt->normal_screen.alternate_charset = FALSE;
- pvt->alternate_screen.alternate_charset = FALSE;
+ /* Reset charset modes. */
+ pvt->character_replacements[0] = VTE_CHARACTER_REPLACEMENT_NONE;
+ pvt->character_replacements[1] = VTE_CHARACTER_REPLACEMENT_NONE;
+ pvt->character_replacement = &pvt->character_replacements[0];
/* Clear the scrollback buffers and reset the cursors. */
if (clear_history) {
_vte_ring_fini(pvt->normal_screen.row_data);
diff --git a/src/vteseq-n.gperf b/src/vteseq-n.gperf
index 424a05d..6792d14 100644
--- a/src/vteseq-n.gperf
+++ b/src/vteseq-n.gperf
@@ -118,8 +118,14 @@ struct vteseq_n_struct {
#"ansi-conformance-level-1", VTE_SEQUENCE_HANDLER_NULL
#"ansi-conformance-level-2", VTE_SEQUENCE_HANDLER_NULL
#"ansi-conformance-level-3", VTE_SEQUENCE_HANDLER_NULL
-"alternate-character-set-start", VTE_SEQUENCE_HANDLER(vte_sequence_handler_alternate_character_set_start)
-"alternate-character-set-end", VTE_SEQUENCE_HANDLER(vte_sequence_handler_alternate_character_set_end)
+"designate-g0-plain", VTE_SEQUENCE_HANDLER(vte_sequence_handler_designate_g0_plain)
+"designate-g0-line-drawing", VTE_SEQUENCE_HANDLER(vte_sequence_handler_designate_g0_line_drawing)
+"designate-g0-british", VTE_SEQUENCE_HANDLER(vte_sequence_handler_designate_g0_british)
+"designate-g1-plain", VTE_SEQUENCE_HANDLER(vte_sequence_handler_designate_g1_plain)
+"designate-g1-line-drawing", VTE_SEQUENCE_HANDLER(vte_sequence_handler_designate_g1_line_drawing)
+"designate-g1-british", VTE_SEQUENCE_HANDLER(vte_sequence_handler_designate_g1_british)
+"shift-in", VTE_SEQUENCE_HANDLER(vte_sequence_handler_shift_in)
+"shift-out", VTE_SEQUENCE_HANDLER(vte_sequence_handler_shift_out)
"change-background-color-bel", VTE_SEQUENCE_HANDLER(vte_sequence_handler_change_background_color_bel)
"change-background-color-st", VTE_SEQUENCE_HANDLER(vte_sequence_handler_change_background_color_st)
"reset-background-color", VTE_SEQUENCE_HANDLER(vte_sequence_handler_reset_background_color)
diff --git a/src/vteseq.c b/src/vteseq.c
index a5726e3..1a76706 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -633,10 +633,6 @@ vte_sequence_handler_decset_internal(VteTerminal *terminal,
NULL, NULL,},
/* 41: more(1) fix. */
/* 42: Enable NLS replacements. */
- {42, PRIV_OFFSET(nrc_mode), 0, 0,
- FALSE,
- TRUE,
- NULL, NULL,},
/* 44: Margin bell. */
{44, PRIV_OFFSET(margin_bell), 0, 0,
FALSE,
@@ -890,18 +886,60 @@ vte_sequence_handler_decset_internal(VteTerminal *terminal,
/* THE HANDLERS */
-/* End alternate character set. */
+/* G0 character set is a pass-thru (no mapping). */
+static void
+vte_sequence_handler_designate_g0_plain (VteTerminal *terminal, GValueArray *params)
+{
+ terminal->pvt->character_replacements[0] = VTE_CHARACTER_REPLACEMENT_NONE;
+}
+
+/* G0 character set is DEC Special Character and Line Drawing Set. */
+static void
+vte_sequence_handler_designate_g0_line_drawing (VteTerminal *terminal, GValueArray *params)
+{
+ terminal->pvt->character_replacements[0] = VTE_CHARACTER_REPLACEMENT_LINE_DRAWING;
+}
+
+/* G0 character set is British (# is converted to £). */
+static void
+vte_sequence_handler_designate_g0_british (VteTerminal *terminal, GValueArray *params)
+{
+ terminal->pvt->character_replacements[0] = VTE_CHARACTER_REPLACEMENT_BRITISH;
+}
+
+/* G1 character set is a pass-thru (no mapping). */
+static void
+vte_sequence_handler_designate_g1_plain (VteTerminal *terminal, GValueArray *params)
+{
+ terminal->pvt->character_replacements[1] = VTE_CHARACTER_REPLACEMENT_NONE;
+}
+
+/* G1 character set is DEC Special Character and Line Drawing Set. */
+static void
+vte_sequence_handler_designate_g1_line_drawing (VteTerminal *terminal, GValueArray *params)
+{
+ terminal->pvt->character_replacements[1] = VTE_CHARACTER_REPLACEMENT_LINE_DRAWING;
+}
+
+/* G1 character set is British (# is converted to £). */
+static void
+vte_sequence_handler_designate_g1_british (VteTerminal *terminal, GValueArray *params)
+{
+ terminal->pvt->character_replacements[1] = VTE_CHARACTER_REPLACEMENT_BRITISH;
+}
+
+/* SI (shift in): switch to G0 character set. */
static void
-vte_sequence_handler_alternate_character_set_end (VteTerminal *terminal, GValueArray *params)
+vte_sequence_handler_shift_in (VteTerminal *terminal, GValueArray *params)
{
- terminal->pvt->screen->alternate_charset = FALSE;
+ terminal->pvt->character_replacement = &terminal->pvt->character_replacements[0];
}
-/* Start using alternate character set. */
+/* SO (shift out): switch to G1 character set. */
static void
-vte_sequence_handler_alternate_character_set_start (VteTerminal *terminal, GValueArray *params)
+vte_sequence_handler_shift_out (VteTerminal *terminal, GValueArray *params)
{
- terminal->pvt->screen->alternate_charset = TRUE;
+ terminal->pvt->character_replacement = &terminal->pvt->character_replacements[1];
}
/* Beep. */
@@ -2160,7 +2198,7 @@ static void
vte_sequence_handler_send_primary_device_attributes (VteTerminal *terminal, GValueArray *params)
{
/* Claim to be a VT220 with only national character set support. */
- vte_terminal_feed_child(terminal, "\e[?62;9;c", -1);
+ vte_terminal_feed_child(terminal, "\e[?62;c", -1);
}
/* Send terminal ID. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]