[vte] widget: Add setting for CJK ambiguous width



commit 1f18737d606346c5c2ab09555a76411ab1ae1a89
Author: Christian Persch <chpe gnome org>
Date:   Mon Mar 31 23:14:02 2014 +0200

    widget: Add setting for CJK ambiguous width
    
    When using UTF-8 encoding, normally ambiguous-width characters are narrow.
    However, some uses (most importantly CJK) want them to be wide instead.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=352654
    https://bugzilla.gnome.org/show_bug.cgi?id=614617

 doc/reference/vte-sections.txt |    2 +
 src/iso2022.c                  |   20 +++++++++--
 src/iso2022.h                  |    4 ++
 src/vte-private.h              |    1 +
 src/vte.c                      |   74 +++++++++++++++++++++++++++++++++++++++-
 src/vte.h                      |    4 ++
 src/vteapp.c                   |   34 ++++++++++++++++++
 7 files changed, 134 insertions(+), 5 deletions(-)
---
diff --git a/doc/reference/vte-sections.txt b/doc/reference/vte-sections.txt
index a873c88..46a8d7a 100644
--- a/doc/reference/vte-sections.txt
+++ b/doc/reference/vte-sections.txt
@@ -64,6 +64,8 @@ vte_terminal_match_check
 vte_terminal_match_set_cursor
 vte_terminal_match_set_cursor_type
 vte_terminal_match_set_cursor_name
+vte_terminal_set_cjk_ambiguous_width
+vte_terminal_get_cjk_ambiguous_width
 vte_terminal_set_emulation
 vte_terminal_get_emulation
 vte_terminal_set_encoding
diff --git a/src/iso2022.c b/src/iso2022.c
index 57b5159..2f857ba 100644
--- a/src/iso2022.c
+++ b/src/iso2022.c
@@ -73,6 +73,7 @@ struct _vte_iso2022_state {
        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;
@@ -338,9 +339,7 @@ _vte_iso2022_ambiguous_width(struct _vte_iso2022_state *state)
         * current locale is UTF-8.
         */
        if (strcmp (codeset, "utf8") == 0) {
-         const char *env = g_getenv ("VTE_CJK_WIDTH");
-         if (env && (g_ascii_strcasecmp (env, "wide")==0 || g_ascii_strcasecmp (env, "1")==0))
-           return 2;
+                return state->utf8_ambiguous_width;
        }
 
        /* Not in the list => not wide. */
@@ -757,10 +756,14 @@ _vte_iso2022_set_encoded_width(gunichar c, int width)
 
 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)
 {
        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;
@@ -797,7 +800,7 @@ _vte_iso2022_state_new(const char *native_codeset,
                                state->codeset, state->target_codeset);
                }
        }
-       state->ambiguous_width = _vte_iso2022_ambiguous_width(state);
+        _vte_iso2022_state_set_utf8_ambiguous_width(state, utf8_ambiguous_width);
        return state;
 }
 
@@ -834,6 +837,7 @@ _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 *
@@ -842,6 +846,14 @@ _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)
 {
diff --git a/src/iso2022.h b/src/iso2022.h
index f25f809..0c186e7 100644
--- a/src/iso2022.h
+++ b/src/iso2022.h
@@ -33,10 +33,13 @@ 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);
 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,
@@ -45,6 +48,7 @@ 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)
diff --git a/src/vte-private.h b/src/vte-private.h
index e5b4647..5ae74c0 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -206,6 +206,7 @@ struct _VteTerminalPrivate {
 
        /* Input data queues. */
        const char *encoding;           /* the pty's encoding */
+        int iso2022_utf8_ambiguous_width;
        struct _vte_iso2022_state *iso2022;
        struct _vte_incoming_chunk{
                struct _vte_incoming_chunk *next;
diff --git a/src/vte.c b/src/vte.c
index 775b675..83e65e0 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -151,6 +151,7 @@ enum {
         PROP_AUDIBLE_BELL,
         PROP_BACKGROUND_TINT_COLOR,
         PROP_BACKSPACE_BINDING,
+        PROP_CJK_AMBIGUOUS_WIDTH,
         PROP_CURSOR_BLINK_MODE,
         PROP_CURSOR_SHAPE,
         PROP_CURRENT_DIRECTORY_URI,
@@ -2037,6 +2038,49 @@ vte_terminal_get_encoding(VteTerminal *terminal)
        return terminal->pvt->encoding;
 }
 
+/**
+ * vte_terminal_set_cjk_ambiguous_width:
+ * @terminal: a #VteTerminal
+ * @width: either 1 (narrow) or 2 (wide)
+ *
+ * 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().
+ *
+ * Since: 0.38
+ */
+void
+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);
+}
+
+/**
+ * vte_terminal_get_cjk_ambiguous_width:
+ * @terminal: a #VteTerminal
+ *
+ * Returns whether ambiguous-width characters are narrow or wide when using
+ * the UTF-8 encoding (vte_terminal_set_encoding()).
+ *
+ * Returns: 1 if ambiguous-width characters are narrow, or 2 if they are wide
+ *
+ * Since: 0.38
+ */
+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;
+}
+
 static inline VteRowData *
 vte_terminal_insert_rows (VteTerminal *terminal, guint cnt)
 {
@@ -8026,7 +8070,9 @@ vte_terminal_init(VteTerminal *terminal)
        _vte_terminal_set_default_attributes(terminal);
 
        /* 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->incoming = NULL;
@@ -10633,6 +10679,9 @@ vte_terminal_get_property (GObject *object,
                 case PROP_BACKSPACE_BINDING:
                         g_value_set_enum (value, pvt->backspace_binding);
                         break;
+                case PROP_CJK_AMBIGUOUS_WIDTH:
+                        g_value_set_int (value, vte_terminal_get_cjk_ambiguous_width (terminal));
+                        break;
                 case PROP_CURSOR_BLINK_MODE:
                         g_value_set_enum (value, vte_terminal_get_cursor_blink_mode (terminal));
                         break;
@@ -10731,6 +10780,9 @@ vte_terminal_set_property (GObject *object,
                 case PROP_BACKSPACE_BINDING:
                         vte_terminal_set_backspace_binding (terminal, g_value_get_enum (value));
                         break;
+                case PROP_CJK_AMBIGUOUS_WIDTH:
+                        vte_terminal_set_cjk_ambiguous_width (terminal, g_value_get_int (value));
+                        break;
                 case PROP_CURSOR_BLINK_MODE:
                         vte_terminal_set_cursor_blink_mode (terminal, g_value_get_enum (value));
                         break;
@@ -11489,6 +11541,25 @@ vte_terminal_class_init(VteTerminalClass *klass)
                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
         /**
+         * VteTerminal:cjk-ambiguous-width:
+         *
+         * 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().
+         * 
+         * Since: 0.38
+         */
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_CURSOR_BLINK_MODE,
+                 g_param_spec_int ("cjk-ambiguous-width", NULL, NULL,
+                                   1, 2, VTE_ISO2022_DEFAULT_UTF8_AMBIGUOUS_WIDTH,
+                                    G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+        /**
          * VteTerminal:cursor-blink-mode:
          *
          * Sets whether or not the cursor will blink. Using %VTE_CURSOR_BLINK_SYSTEM
@@ -11503,7 +11574,7 @@ vte_terminal_class_init(VteTerminalClass *klass)
                                     VTE_TYPE_TERMINAL_CURSOR_BLINK_MODE,
                                     VTE_CURSOR_BLINK_SYSTEM,
                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-     
+
         /**
          * VteTerminal:cursor-shape:
          *
@@ -12625,6 +12696,7 @@ vte_terminal_reset(VteTerminal *terminal,
        /* 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);
        _vte_iso2022_state_set_codeset(pvt->iso2022,
diff --git a/src/vte.h b/src/vte.h
index 6081f06..e956db0 100644
--- a/src/vte.h
+++ b/src/vte.h
@@ -365,6 +365,10 @@ const char *vte_get_default_emulation(void);
 void vte_terminal_set_encoding(VteTerminal *terminal, const char *codeset);
 const char *vte_terminal_get_encoding(VteTerminal *terminal);
 
+/* CJK compatibility setting */
+void vte_terminal_set_cjk_ambiguous_width(VteTerminal *terminal, int width);
+int vte_terminal_get_cjk_ambiguous_width(VteTerminal *terminal);
+
 /* Get the contents of the status line. */
 const char *vte_terminal_get_status_line(VteTerminal *terminal);
 
diff --git a/src/vteapp.c b/src/vteapp.c
index 55dcfbd..114fe5b 100644
--- a/src/vteapp.c
+++ b/src/vteapp.c
@@ -541,6 +541,8 @@ main(int argc, char **argv)
 #endif
                NULL};
         char *transparent = NULL;
+        char *encoding = NULL;
+        char *cjk_ambiguous_width = NULL;
        gboolean audible = TRUE,
                 debug = FALSE, dingus = FALSE, dbuffer = TRUE,
                 console = FALSE, keep = FALSE,
@@ -660,6 +662,16 @@ main(int argc, char **argv)
                        "Specify the terminal emulation to use", NULL
                },
                {
+                       "encoding", 0, 0,
+                       G_OPTION_ARG_STRING, &encoding,
+                       "Specify the terminal encoding to use", NULL
+               },
+               {
+                       "cjk-width", 0, 0,
+                       G_OPTION_ARG_STRING, &cjk_ambiguous_width,
+                       "Specify the cjk ambiguous width to use for UTF-8 encoding", "NARROW|WIDE"
+               },
+               {
                        "working-directory", 'w', 0,
                        G_OPTION_ARG_FILENAME, &working_directory,
                        "Specify the initial working directory of the terminal",
@@ -726,6 +738,9 @@ main(int argc, char **argv)
                        g_mem_set_vtable(glib_mem_profiler_table);
                }
        }
+        if (g_getenv("VTE_CJK_WIDTH")) {
+                g_printerr("VTE_CJK_WIDTH is not supported anymore, use --cjk-width instead\n");
+        }
 
        context = g_option_context_new (" - test VTE terminal emulation");
        g_option_context_add_main_entries (context, options, NULL);
@@ -898,6 +913,25 @@ main(int argc, char **argv)
        if (termcap != NULL) {
                vte_terminal_set_emulation(terminal, termcap);
        }
+        if (encoding != NULL) {
+                vte_terminal_set_encoding(terminal, encoding);
+                g_free(encoding);
+        }
+        if (cjk_ambiguous_width != NULL) {
+                int width = 1;
+
+                if (g_ascii_strcasecmp(cjk_ambiguous_width, "narrow") == 0)
+                        width = 1;
+                else if (g_ascii_strcasecmp(cjk_ambiguous_width, "wide") == 0)
+                        width = 2;
+                else
+                        g_printerr("Unrecognised value \"%s\" for --cjk-width\n",
+                                   cjk_ambiguous_width);
+                g_free(cjk_ambiguous_width);
+
+                vte_terminal_set_cjk_ambiguous_width(terminal, width);
+        }
+
        vte_terminal_set_cursor_shape(terminal, cursor_shape);
 
        vte_terminal_set_rewrap_on_resize(terminal, rewrap);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]