[vte] emulation: Drop ISO-2022 support



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]