chiark / gitweb /
shared: utf8 - support ucs4 -> utf8
[elogind.git] / src / libsystemd-terminal / term-screen.c
index 5a053a31bd28371e82d23caf2ce80652f36734d8..0e38ff41c63f5b5278979a5109620ab1e7b5be49 100644 (file)
@@ -51,6 +51,7 @@
 #include "macro.h"
 #include "term-internal.h"
 #include "util.h"
+#include "utf8.h"
 
 int term_screen_new(term_screen **out, term_screen_write_fn write_fn, void *write_fn_data, term_screen_cmd_fn cmd_fn, void *cmd_fn_data) {
         _cleanup_(term_screen_unrefp) term_screen *screen = NULL;
@@ -392,126 +393,117 @@ static inline void set_reset(term_screen *screen, unsigned int flag, bool set) {
                 screen->flags &= ~flag;
 }
 
-static void screen_mode_change(term_screen *screen, unsigned int mode, bool dec, bool set) {
+static void screen_mode_change_ansi(term_screen *screen, unsigned mode, bool set) {
+        switch (mode) {
+        case 20:
+                /*
+                 * LNM: line-feed/new-line mode
+                 * TODO
+                 */
+                set_reset(screen, TERM_FLAG_NEWLINE_MODE, set);
+
+                break;
+        default:
+                log_debug("terminal: failed to %s unknown ANSI mode %u", set ? "set" : "unset", mode);
+        }
+}
+
+static void screen_mode_change_dec(term_screen *screen, unsigned int mode, bool set) {
         switch (mode) {
         case 1:
-                if (dec) {
-                        /*
-                         * DECCKM: cursor-keys
-                         * TODO
-                         */
-                        set_reset(screen, TERM_FLAG_CURSOR_KEYS, set);
-                }
+                /*
+                 * DECCKM: cursor-keys
+                 * TODO
+                 */
+                set_reset(screen, TERM_FLAG_CURSOR_KEYS, set);
 
                 break;
         case 6:
-                if (dec) {
-                        /*
-                         * DECOM: origin-mode
-                         * TODO
-                         */
-                        screen->state.origin_mode = set;
-                }
+                /*
+                 * DECOM: origin-mode
+                 * TODO
+                 */
+                screen->state.origin_mode = set;
 
                 break;
         case 7:
-                if (dec) {
-                        /*
-                         * DECAWN: auto-wrap mode
-                         * TODO
-                         */
-                        screen->state.auto_wrap = set;
-                }
-
-                break;
-        case 20:
-                if (!dec) {
-                        /*
-                         * LNM: line-feed/new-line mode
-                         * TODO
-                         */
-                        set_reset(screen, TERM_FLAG_NEWLINE_MODE, set);
-                }
+                /*
+                 * DECAWN: auto-wrap mode
+                 * TODO
+                 */
+                screen->state.auto_wrap = set;
 
                 break;
         case 25:
-                if (dec) {
-                        /*
-                         * DECTCEM: text-cursor-enable
-                         * TODO
-                         */
-                        set_reset(screen, TERM_FLAG_HIDE_CURSOR, !set);
-                        screen_age_cursor(screen);
-                }
+                /*
+                 * DECTCEM: text-cursor-enable
+                 * TODO
+                 */
+                set_reset(screen, TERM_FLAG_HIDE_CURSOR, !set);
+                screen_age_cursor(screen);
 
                 break;
         case 47:
-                if (dec) {
-                        /*
-                         * XTERM-ASB: alternate-screen-buffer
-                         * This enables/disables the alternate screen-buffer.
-                         * It effectively saves the current page content and
-                         * allows you to restore it when changing to the
-                         * original screen-buffer again.
-                         */
-                        screen_change_alt(screen, set);
-                }
+                /*
+                 * XTERM-ASB: alternate-screen-buffer
+                 * This enables/disables the alternate screen-buffer.
+                 * It effectively saves the current page content and
+                 * allows you to restore it when changing to the
+                 * original screen-buffer again.
+                 */
+                screen_change_alt(screen, set);
 
                 break;
         case 1047:
-                if (dec) {
-                        /*
-                         * XTERM-ASBPE: alternate-screen-buffer-post-erase
-                         * This is the same as XTERM-ASB but erases the
-                         * alternate screen-buffer before switching back to the
-                         * original buffer. Use it to discard any data on the
-                         * alternate screen buffer when done.
-                         */
-                        if (!set)
-                                screen_reset_page(screen, screen->page_alt);
-
-                        screen_change_alt(screen, set);
-                }
+                /*
+                 * XTERM-ASBPE: alternate-screen-buffer-post-erase
+                 * This is the same as XTERM-ASB but erases the
+                 * alternate screen-buffer before switching back to the
+                 * original buffer. Use it to discard any data on the
+                 * alternate screen buffer when done.
+                 */
+                if (!set)
+                        screen_reset_page(screen, screen->page_alt);
+
+                screen_change_alt(screen, set);
 
                 break;
         case 1048:
-                if (dec) {
-                        /*
-                         * XTERM-ASBCS: alternate-screen-buffer-cursor-state
-                         * This has the same effect as DECSC/DECRC, but uses a
-                         * separate state buffer. It is usually used in
-                         * combination with alternate screen buffers to provide
-                         * stacked state storage.
-                         */
-                        if (set)
-                                screen_save_state(screen, &screen->saved_alt);
-                        else
-                                screen_restore_state(screen, &screen->saved_alt);
-                }
+                /*
+                 * XTERM-ASBCS: alternate-screen-buffer-cursor-state
+                 * This has the same effect as DECSC/DECRC, but uses a
+                 * separate state buffer. It is usually used in
+                 * combination with alternate screen buffers to provide
+                 * stacked state storage.
+                 */
+                if (set)
+                        screen_save_state(screen, &screen->saved_alt);
+                else
+                        screen_restore_state(screen, &screen->saved_alt);
 
                 break;
         case 1049:
-                if (dec) {
-                        /*
-                         * XTERM-ASBX: alternate-screen-buffer-extended
-                         * This combines XTERM-ASBPE and XTERM-ASBCS somewhat.
-                         * When enabling, state is saved, alternate screen
-                         * buffer is activated and cleared.
-                         * When disabled, alternate screen buffer is cleared,
-                         * then normal screen buffer is enabled and state is
-                         * restored.
-                         */
-                        if (set)
-                                screen_save_state(screen, &screen->saved_alt);
-
-                        screen_reset_page(screen, screen->page_alt);
-                        screen_change_alt(screen, set);
-
-                        if (!set)
-                                screen_restore_state(screen, &screen->saved_alt);
-                }
+                /*
+                 * XTERM-ASBX: alternate-screen-buffer-extended
+                 * This combines XTERM-ASBPE and XTERM-ASBCS somewhat.
+                 * When enabling, state is saved, alternate screen
+                 * buffer is activated and cleared.
+                 * When disabled, alternate screen buffer is cleared,
+                 * then normal screen buffer is enabled and state is
+                 * restored.
+                 */
+                if (set)
+                        screen_save_state(screen, &screen->saved_alt);
+
+                screen_reset_page(screen, screen->page_alt);
+                screen_change_alt(screen, set);
+
+                if (!set)
+                        screen_restore_state(screen, &screen->saved_alt);
 
                 break;
+        default:
+                log_debug("terminal: failed to %s unknown DEC mode %u", set ? "set" : "unset", mode);
         }
 }
 
@@ -558,7 +550,6 @@ static int screen_LF(term_screen *screen, const term_seq *seq);
 
 static int screen_GRAPHIC(term_screen *screen, const term_seq *seq) {
         term_char_t ch = TERM_CHAR_NULL;
-        uint32_t c;
 
         if (screen->state.cursor_x + 1 == screen->page->width
             && screen->flags & TERM_FLAG_PENDING_WRAP
@@ -569,8 +560,7 @@ static int screen_GRAPHIC(term_screen *screen, const term_seq *seq) {
 
         screen_cursor_clear_wrap(screen);
 
-        c = screen_map(screen, seq->terminator);
-        ch = term_char_merge(ch, screen_map(screen, c));
+        ch = term_char_merge(ch, screen_map(screen, seq->terminator));
         term_page_write(screen->page, screen->state.cursor_x, screen->state.cursor_y, ch, 1, &screen->state.attr, screen->age, false);
 
         if (screen->state.cursor_x + 1 == screen->page->width)
@@ -2763,7 +2753,7 @@ static int screen_RM_ANSI(term_screen *screen, const term_seq *seq) {
         unsigned int i;
 
         for (i = 0; i < seq->n_args; ++i)
-                screen_mode_change(screen, seq->args[i], false, false);
+                screen_mode_change_ansi(screen, seq->args[i], false);
 
         return 0;
 }
@@ -2777,7 +2767,7 @@ static int screen_RM_DEC(term_screen *screen, const term_seq *seq) {
         unsigned int i;
 
         for (i = 0; i < seq->n_args; ++i)
-                screen_mode_change(screen, seq->args[i], true, false);
+                screen_mode_change_dec(screen, seq->args[i], false);
 
         return 0;
 }
@@ -3057,7 +3047,7 @@ static int screen_SM_ANSI(term_screen *screen, const term_seq *seq) {
         unsigned int i;
 
         for (i = 0; i < seq->n_args; ++i)
-                screen_mode_change(screen, seq->args[i], false, true);
+                screen_mode_change_ansi(screen, seq->args[i], true);
 
         return 0;
 }
@@ -3071,7 +3061,7 @@ static int screen_SM_DEC(term_screen *screen, const term_seq *seq) {
         unsigned int i;
 
         for (i = 0; i < seq->n_args; ++i)
-                screen_mode_change(screen, seq->args[i], true, true);
+                screen_mode_change_dec(screen, seq->args[i], true);
 
         return 0;
 }
@@ -3195,7 +3185,7 @@ static int screen_TBC(term_screen *screen, const term_seq *seq) {
                 break;
         case 3:
                 if (screen->page->width > 0)
-                        memset(screen->tabs, 0, (screen->page->width + 7) / 8);
+                        memzero(screen->tabs, (screen->page->width + 7) / 8);
                 break;
         }
 
@@ -4118,7 +4108,7 @@ static char *screen_map_key(term_screen *screen,
 
         /* map unicode keys */
         for (i = 0; i < n_syms; ++i)
-                p += term_utf8_encode(p, ucs4[i]);
+                p += utf8_encode_unichar(p, ucs4[i]);
 
         return p;
 }