console/vte: implement ICH DCH
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sat, 14 Jul 2012 15:33:28 +0000 (17:33 +0200)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sat, 14 Jul 2012 15:33:28 +0000 (17:33 +0200)
ICH is used to insert characters into the current line. DCH is used to
delete characters from the current line. They act as described in vt220
manual.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
src/console.c
src/console.h
src/vte.c

index e1f1714..9627813 100644 (file)
@@ -1003,6 +1003,64 @@ void kmscon_console_delete_lines(struct kmscon_console *con, unsigned int num)
        con->cursor_x = 0;
 }
 
+void kmscon_console_insert_chars(struct kmscon_console *con, unsigned int num)
+{
+       struct cell *cells;
+       unsigned int max, mv, i;
+
+       if (!con || !num || !con->size_y || !con->size_x)
+               return;
+
+       if (con->cursor_x >= con->size_x)
+               con->cursor_x = con->size_x - 1;
+       if (con->cursor_y >= con->size_y)
+               con->cursor_y = con->size_y - 1;
+
+       max = con->size_x - con->cursor_x;
+       if (num > max)
+               num = max;
+       mv = max - num;
+
+       cells = con->lines[con->cursor_y]->cells;
+       if (mv)
+               memmove(&cells[con->cursor_x + num],
+                       &cells[con->cursor_x],
+                       mv * sizeof(*cells));
+
+       for (i = 0; i < num; ++i) {
+               cell_init(con, &cells[con->cursor_x + i]);
+       }
+}
+
+void kmscon_console_delete_chars(struct kmscon_console *con, unsigned int num)
+{
+       struct cell *cells;
+       unsigned int max, mv, i;
+
+       if (!con || !num || !con->size_y || !con->size_x)
+               return;
+
+       if (con->cursor_x >= con->size_x)
+               con->cursor_x = con->size_x - 1;
+       if (con->cursor_y >= con->size_y)
+               con->cursor_y = con->size_y - 1;
+
+       max = con->size_x - con->cursor_x;
+       if (num > max)
+               num = max;
+       mv = max - num;
+
+       cells = con->lines[con->cursor_y]->cells;
+       if (mv)
+               memmove(&cells[con->cursor_x],
+                       &cells[con->cursor_x + num],
+                       mv * sizeof(*cells));
+
+       for (i = 0; i < num; ++i) {
+               cell_init(con, &cells[con->cursor_x + mv + i]);
+       }
+}
+
 void kmscon_console_erase_cursor(struct kmscon_console *con)
 {
        unsigned int x;
index ee0897c..6c02d03 100644 (file)
@@ -93,6 +93,8 @@ void kmscon_console_move_line_end(struct kmscon_console *con);
 void kmscon_console_move_line_home(struct kmscon_console *con);
 void kmscon_console_insert_lines(struct kmscon_console *con, unsigned int num);
 void kmscon_console_delete_lines(struct kmscon_console *con, unsigned int num);
+void kmscon_console_insert_chars(struct kmscon_console *con, unsigned int num);
+void kmscon_console_delete_chars(struct kmscon_console *con, unsigned int num);
 void kmscon_console_erase_cursor(struct kmscon_console *con);
 void kmscon_console_erase_cursor_to_end(struct kmscon_console *con);
 void kmscon_console_erase_home_to_cursor(struct kmscon_console *con);
index c9f2ef1..c595683 100644 (file)
--- a/src/vte.c
+++ b/src/vte.c
@@ -1197,6 +1197,20 @@ static void do_csi(struct kmscon_vte *vte, uint32_t data)
                else
                        log_debug("invalid parameter %d to TBC CSI", num);
                break;
+       case '@': /* ICH */
+               /* insert characters */
+               num = vte->csi_argv[0];
+               if (num <= 0)
+                       num = 1;
+               kmscon_console_insert_chars(vte->con, num);
+               break;
+       case 'P': /* DCH */
+               /* delete characters */
+               num = vte->csi_argv[0];
+               if (num <= 0)
+                       num = 1;
+               kmscon_console_delete_chars(vte->con, num);
+               break;
        default:
                log_debug("unhandled CSI sequence %c", data);
        }