[vte] emulation: Save/restore alternate charset



commit 5a434e6c4457bdfe182a13213396e7a66a08f767
Author: Egmont Koblinger <egmont gmail com>
Date:   Sat Nov 22 19:20:35 2014 +0100

    emulation: Save/restore alternate charset
    
    https://bugzilla.gnome.org/show_bug.cgi?id=731205

 src/vte-private.h |   67 +++++---
 src/vte.c         |  281 ++++++++++++++----------------
 src/vteseq.c      |  502 +++++++++++++++++++++++++++++------------------------
 3 files changed, 442 insertions(+), 408 deletions(-)
---
diff --git a/src/vte-private.h b/src/vte-private.h
index 77de804..3e36b21 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -246,34 +246,45 @@ struct _VteTerminalPrivate {
         * screen, which seems to be a DEC-specific feature. */
        struct _VteScreen {
                VteRing row_data[1];    /* buffer contents */
-               VteVisualPosition cursor_current, cursor_saved;
-                                       /* the current and saved positions of
-                                          the [insertion] cursor -- current is
-                                          absolute, saved is relative to the
-                                          insertion delta */
-               gboolean reverse_mode;  /* reverse mode */
-               gboolean origin_mode;   /* origin mode */
-               gboolean sendrecv_mode; /* sendrecv mode */
-               gboolean insert_mode;   /* insert mode */
-               gboolean linefeed_mode; /* linefeed mode */
-               struct vte_scrolling_region {
-                       int start, end;
-               } scrolling_region;     /* the region we scroll in */
-               gboolean scrolling_restricted;
                long scroll_delta;      /* scroll offset */
                long insert_delta;      /* insertion offset */
-               VteCell defaults;       /* default characteristics
-                                          for insertion of any new
-                                          characters */
-               VteCell color_defaults; /* original defaults
-                                          plus the current
-                                          fore/back */
-               VteCell fill_defaults;  /* original defaults
-                                          plus the current
-                                          fore/back with no
-                                          character data */
+
+                /* Stuff saved along with the cursor */
+                struct {
+                        VteVisualPosition cursor;
+                        gboolean reverse_mode;
+                        gboolean origin_mode;
+                        gboolean sendrecv_mode;
+                        gboolean insert_mode;
+                        gboolean linefeed_mode;
+                        VteCell defaults;
+                        VteCell color_defaults;
+                        VteCell fill_defaults;
+                        VteCharacterReplacement character_replacements[2];
+                        VteCharacterReplacement *character_replacement;
+                } saved;
        } normal_screen, alternate_screen, *screen;
 
+        /* Values we save along with the cursor */
+        VteVisualPosition cursor;      /* relative to the insertion delta */
+        gboolean reverse_mode; /* reverse mode */
+        gboolean origin_mode;  /* origin mode */
+        gboolean sendrecv_mode;        /* sendrecv mode */
+        gboolean insert_mode;  /* insert mode */
+        gboolean linefeed_mode;        /* linefeed mode */
+        VteCell defaults;      /* default characteristics
+                                   for insertion of any new
+                                   characters */
+        VteCell color_defaults;        /* original defaults
+                                   plus the current
+                                   fore/back */
+        VteCell fill_defaults; /* original defaults
+                                   plus the current
+                                   fore/back with no
+                                   character data */
+        VteCharacterReplacement character_replacements[2];  /* charsets in the G0 and G1 slots */
+        VteCharacterReplacement *character_replacement;     /* pointer to the active one */
+
        /* Selection information. */
        gboolean has_selection;
        gboolean selecting;
@@ -306,8 +317,6 @@ 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;
@@ -316,6 +325,12 @@ struct _VteTerminalPrivate {
        gboolean alternate_screen_scroll;
        long scrollback_lines;
 
+        /* Restricted scrolling */
+        struct vte_scrolling_region {
+                int start, end;
+        } scrolling_region;     /* the region we scroll in */
+        gboolean scrolling_restricted;
+
        /* Cursor shape, as set via API */
        VteCursorShape cursor_shape;
         float cursor_aspect_ratio;
diff --git a/src/vte.c b/src/vte.c
index 2154b36..9ee5e73 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -327,12 +327,12 @@ _vte_terminal_ring_insert (VteTerminal *terminal, glong position, gboolean fill)
        VteRing *ring = terminal->pvt->screen->row_data;
        while (G_UNLIKELY (_vte_ring_next (ring) < position)) {
                row = _vte_ring_append (ring);
-               if (terminal->pvt->screen->fill_defaults.attr.back != VTE_DEFAULT_BG)
-                       _vte_row_data_fill (row, &terminal->pvt->screen->fill_defaults, 
terminal->pvt->column_count);
+                if (terminal->pvt->fill_defaults.attr.back != VTE_DEFAULT_BG)
+                        _vte_row_data_fill (row, &terminal->pvt->fill_defaults, terminal->pvt->column_count);
        }
        row = _vte_ring_insert (ring, position);
-       if (fill && terminal->pvt->screen->fill_defaults.attr.back != VTE_DEFAULT_BG)
-               _vte_row_data_fill (row, &terminal->pvt->screen->fill_defaults, terminal->pvt->column_count);
+        if (fill && terminal->pvt->fill_defaults.attr.back != VTE_DEFAULT_BG)
+                _vte_row_data_fill (row, &terminal->pvt->fill_defaults, terminal->pvt->column_count);
        return row;
 }
 
@@ -352,13 +352,9 @@ _vte_terminal_ring_remove (VteTerminal *terminal, glong position)
 void
 _vte_terminal_set_default_attributes(VteTerminal *terminal)
 {
-       VteScreen *screen;
-
-       screen = terminal->pvt->screen;
-
-       screen->defaults = basic_cell.cell;
-       screen->color_defaults = screen->defaults;
-       screen->fill_defaults = screen->defaults;
+        terminal->pvt->defaults = basic_cell.cell;
+        terminal->pvt->color_defaults = terminal->pvt->defaults;
+        terminal->pvt->fill_defaults = terminal->pvt->defaults;
 }
 
 /* Cause certain cells to be repainted. */
@@ -715,7 +711,6 @@ _vte_invalidate_cell(VteTerminal *terminal, glong col, glong row)
 void
 _vte_invalidate_cursor_once(VteTerminal *terminal, gboolean periodic)
 {
-       VteScreen *screen;
        const VteCell *cell;
        gssize preedit_width;
        glong column, row;
@@ -738,9 +733,8 @@ _vte_invalidate_cursor_once(VteTerminal *terminal, gboolean periodic)
        if (terminal->pvt->cursor_visible) {
                preedit_width = vte_terminal_preedit_width(terminal, FALSE);
 
-               screen = terminal->pvt->screen;
-               row = screen->cursor_current.row;
-               column = screen->cursor_current.col;
+                row = terminal->pvt->cursor.row;
+                column = terminal->pvt->cursor.col;
                columns = 1;
                column = find_start_column (terminal, column, row);
                cell = vte_terminal_find_charcell(terminal, column, row);
@@ -1756,7 +1750,7 @@ vte_terminal_emit_adjustment_changed(VteTerminal *terminal)
                /* The upper value is the number of rows which might be visible.  (Add
                 * one to the cursor offset because it's zero-based.) */
                v = MAX(_vte_ring_next(screen->row_data),
-                               screen->cursor_current.row + 1);
+                        terminal->pvt->cursor.row + 1);
                current = gtk_adjustment_get_upper(terminal->pvt->vadjustment);
                if (current != v) {
                        _vte_debug_print(VTE_DEBUG_ADJ,
@@ -1842,8 +1836,8 @@ _vte_terminal_adjust_adjustments(VteTerminal *terminal)
         * area.  Leave the scrolling delta alone because it will be updated
         * when the adjustment changes. */
        screen->insert_delta = MAX(screen->insert_delta, delta);
-       screen->cursor_current.row = MAX(screen->cursor_current.row,
-                                        screen->insert_delta);
+        terminal->pvt->cursor.row = MAX(terminal->pvt->cursor.row,
+                                        screen->insert_delta);
 
        if (screen->scroll_delta > screen->insert_delta) {
                vte_terminal_queue_adjustment_value_changed(terminal,
@@ -2136,7 +2130,7 @@ _vte_terminal_ensure_row (VteTerminal *terminal)
 
        /* Must make sure we're in a sane area. */
        screen = terminal->pvt->screen;
-       v = screen->cursor_current.row;
+        v = terminal->pvt->cursor.row;
 
        /* Figure out how many rows we need to add. */
        delta = v - _vte_ring_next(screen->row_data) + 1;
@@ -2158,7 +2152,7 @@ vte_terminal_ensure_cursor(VteTerminal *terminal)
        VteRowData *row;
 
        row = _vte_terminal_ensure_row (terminal);
-       _vte_row_data_fill (row, &basic_cell.cell, terminal->pvt->screen->cursor_current.col);
+        _vte_row_data_fill (row, &basic_cell.cell, terminal->pvt->cursor.col);
 
        return row;
 }
@@ -2176,7 +2170,7 @@ _vte_terminal_update_insert_delta(VteTerminal *terminal)
        /* The total number of lines.  Add one to the cursor offset
         * because it's zero-based. */
        rows = _vte_ring_next (screen->row_data);
-       delta = screen->cursor_current.row - rows + 1;
+        delta = terminal->pvt->cursor.row - rows + 1;
        if (G_UNLIKELY (delta > 0)) {
                vte_terminal_insert_rows (terminal, delta);
                rows = _vte_ring_next (screen->row_data);
@@ -2188,7 +2182,7 @@ _vte_terminal_update_insert_delta(VteTerminal *terminal)
        delta = screen->insert_delta;
        delta = MIN(delta, rows - terminal->pvt->row_count);
        delta = MAX(delta,
-                   screen->cursor_current.row - (terminal->pvt->row_count - 1));
+                    terminal->pvt->cursor.row - (terminal->pvt->row_count - 1));
        delta = MAX(delta, _vte_ring_delta(screen->row_data));
 
        /* Adjust the insert delta and scroll if needed. */
@@ -2928,7 +2922,7 @@ _vte_terminal_cleanup_fragments(VteTerminal *terminal,
                         cell_end->attr.columns = 1;
                         _vte_invalidate_cells(terminal,
                                               end, 1,
-                                              terminal->pvt->screen->cursor_current.row, 1);
+                                              terminal->pvt->cursor.row, 1);
                 }
         }
 
@@ -2954,7 +2948,7 @@ _vte_terminal_cleanup_fragments(VteTerminal *terminal,
                                         g_assert(start - col == 1);
                                         _vte_invalidate_cells(terminal,
                                                               col, 1,
-                                                              terminal->pvt->screen->cursor_current.row, 1);
+                                                              terminal->pvt->cursor.row, 1);
                                 }
                                 keep_going = FALSE;
                         }
@@ -2974,26 +2968,26 @@ _vte_terminal_cursor_down (VteTerminal *terminal)
 
        screen = terminal->pvt->screen;
 
-       if (screen->scrolling_restricted) {
-               start = screen->insert_delta + screen->scrolling_region.start;
-               end = screen->insert_delta + screen->scrolling_region.end;
+        if (terminal->pvt->scrolling_restricted) {
+                start = screen->insert_delta + terminal->pvt->scrolling_region.start;
+                end = screen->insert_delta + terminal->pvt->scrolling_region.end;
        } else {
                start = screen->insert_delta;
                end = start + terminal->pvt->row_count - 1;
        }
-       if (screen->cursor_current.row == end) {
-               if (screen->scrolling_restricted) {
+        if (terminal->pvt->cursor.row == end) {
+                if (terminal->pvt->scrolling_restricted) {
                        if (start == screen->insert_delta) {
                                /* Scroll this line into the scrollback
                                 * buffer by inserting a line at the next
                                 * line and scrolling the area up. */
                                screen->insert_delta++;
-                               screen->cursor_current.row++;
+                                terminal->pvt->cursor.row++;
                                /* update start and end, as they are relative
                                 * to insert_delta. */
                                start++;
                                end++;
-                               _vte_terminal_ring_insert (terminal, screen->cursor_current.row, FALSE);
+                                _vte_terminal_ring_insert (terminal, terminal->pvt->cursor.row, FALSE);
                                /* Force the areas below the region to be
                                 * redrawn -- they've moved. */
                                _vte_terminal_scroll_region(terminal, start,
@@ -3015,19 +3009,19 @@ _vte_terminal_cursor_down (VteTerminal *terminal)
                        }
                } else {
                        /* Scroll up with history. */
-                       screen->cursor_current.row++;
+                        terminal->pvt->cursor.row++;
                        _vte_terminal_update_insert_delta(terminal);
                }
 
                /* Match xterm and fill the new row when scrolling. */
-               if (screen->fill_defaults.attr.back != VTE_DEFAULT_BG) {
+                if (terminal->pvt->fill_defaults.attr.back != VTE_DEFAULT_BG) {
                        VteRowData *rowdata;
                        rowdata = _vte_terminal_ensure_row (terminal);
-                       _vte_row_data_fill (rowdata, &screen->fill_defaults, terminal->pvt->column_count);
+                        _vte_row_data_fill (rowdata, &terminal->pvt->fill_defaults, 
terminal->pvt->column_count);
                }
        } else {
                /* Otherwise, just move the cursor down. */
-               screen->cursor_current.row++;
+                terminal->pvt->cursor.row++;
        }
 }
 
@@ -3079,7 +3073,7 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
         };
 
        screen = terminal->pvt->screen;
-       insert |= screen->insert_mode;
+        insert |= terminal->pvt->insert_mode;
        invalidate_now |= insert;
 
        /* If we've enabled the special drawing set, map the characters to
@@ -3096,21 +3090,21 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
         columns = _vte_unichar_width(c, terminal->pvt->utf8_ambiguous_width);
 
        /* If we're autowrapping here, do it. */
-       col = screen->cursor_current.col;
+        col = terminal->pvt->cursor.col;
        if (G_UNLIKELY (columns && col + columns > terminal->pvt->column_count)) {
                if (terminal->pvt->autowrap) {
                        _vte_debug_print(VTE_DEBUG_ADJ,
                                        "Autowrapping before character\n");
                        /* Wrap. */
                        /* XXX clear to the end of line */
-                       col = screen->cursor_current.col = 0;
+                        col = terminal->pvt->cursor.col = 0;
                        /* Mark this line as soft-wrapped. */
                        row = _vte_terminal_ensure_row (terminal);
                        row->attr.soft_wrapped = 1;
                        _vte_terminal_cursor_down (terminal);
                } else {
                        /* Don't wrap, stay at the rightmost column. */
-                       col = screen->cursor_current.col =
+                        col = terminal->pvt->cursor.col =
                                terminal->pvt->column_count - columns;
                }
                line_wrapped = TRUE;
@@ -3119,9 +3113,9 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
        _vte_debug_print(VTE_DEBUG_PARSE,
                        "Inserting %ld '%c' (%d/%d) (%ld+%d, %ld), delta = %ld; ",
                        (long)c, c < 256 ? c : ' ',
-                       screen->color_defaults.attr.fore,
-                       screen->color_defaults.attr.back,
-                       col, columns, (long)screen->cursor_current.row,
+                        terminal->pvt->color_defaults.attr.fore,
+                        terminal->pvt->color_defaults.attr.back,
+                        col, columns, (long)terminal->pvt->cursor.row,
                        (long)screen->insert_delta);
 
 
@@ -3134,7 +3128,7 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
 
                _vte_debug_print(VTE_DEBUG_PARSE, "combining U+%04X", c);
 
-               row_num = screen->cursor_current.row;
+                row_num = terminal->pvt->cursor.row;
                row = NULL;
                if (G_UNLIKELY (col == 0)) {
                        /* We are at first column.  See if the previous line softwrapped.
@@ -3199,15 +3193,15 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
        if (insert) {
                 _vte_terminal_cleanup_fragments (terminal, col, col);
                for (i = 0; i < columns; i++)
-                       _vte_row_data_insert (row, col + i, &screen->color_defaults);
+                        _vte_row_data_insert (row, col + i, &terminal->pvt->color_defaults);
        } else {
                 _vte_terminal_cleanup_fragments (terminal, col, col + columns);
                _vte_row_data_fill (row, &basic_cell.cell, col + columns);
        }
 
-       attr = screen->defaults.attr;
-       attr.fore = screen->color_defaults.attr.fore;
-       attr.back = screen->color_defaults.attr.back;
+        attr = terminal->pvt->defaults.attr;
+        attr.fore = terminal->pvt->color_defaults.attr.fore;
+        attr.back = terminal->pvt->color_defaults.attr.back;
        attr.columns = columns;
 
        {
@@ -3234,10 +3228,10 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
                _vte_invalidate_cells(terminal,
                                col - columns,
                                insert ? terminal->pvt->column_count : columns,
-                               screen->cursor_current.row, 1);
+                                terminal->pvt->cursor.row, 1);
        }
 
-       screen->cursor_current.col = col;
+        terminal->pvt->cursor.col = col;
 
 done:
        /* We added text, so make a note of it. */
@@ -3648,12 +3642,12 @@ vte_terminal_process_incoming(VteTerminal *terminal)
        bottom = screen->insert_delta == delta;
 
        /* Save the current cursor position. */
-       cursor = screen->cursor_current;
+        cursor = terminal->pvt->cursor;
        cursor_visible = terminal->pvt->cursor_visible;
 
-       in_scroll_region = screen->scrolling_restricted
-           && (screen->cursor_current.row >= (screen->insert_delta + screen->scrolling_region.start))
-           && (screen->cursor_current.row <= (screen->insert_delta + screen->scrolling_region.end));
+        in_scroll_region = terminal->pvt->scrolling_restricted
+            && (terminal->pvt->cursor.row >= (screen->insert_delta + terminal->pvt->scrolling_region.start))
+            && (terminal->pvt->cursor.row <= (screen->insert_delta + terminal->pvt->scrolling_region.end));
 
        /* We should only be called when there's data to process. */
        g_assert(terminal->pvt->incoming ||
@@ -3762,9 +3756,9 @@ skip_chunk:
                        start = (next - wbuf);
                        modified = TRUE;
 
-                       new_in_scroll_region = screen->scrolling_restricted
-                           && (screen->cursor_current.row >= (screen->insert_delta + 
screen->scrolling_region.start))
-                           && (screen->cursor_current.row <= (screen->insert_delta + 
screen->scrolling_region.end));
+                        new_in_scroll_region = terminal->pvt->scrolling_restricted
+                            && (terminal->pvt->cursor.row >= (screen->insert_delta + 
terminal->pvt->scrolling_region.start))
+                            && (terminal->pvt->cursor.row <= (screen->insert_delta + 
terminal->pvt->scrolling_region.end));
 
                        delta = screen->scroll_delta;   /* delta may have changed from sequence. */
 
@@ -3773,10 +3767,10 @@ skip_chunk:
                          */
                        if (invalidated_text &&
                                        ((new_in_scroll_region && !in_scroll_region) ||
-                                        (screen->cursor_current.col > bbox_bottomright.x + 
VTE_CELL_BBOX_SLACK ||
-                                         screen->cursor_current.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK   
  ||
-                                         screen->cursor_current.row > bbox_bottomright.y + 
VTE_CELL_BBOX_SLACK ||
-                                         screen->cursor_current.row < bbox_topleft.y - 
VTE_CELL_BBOX_SLACK))) {
+                                         (terminal->pvt->cursor.col > bbox_bottomright.x + 
VTE_CELL_BBOX_SLACK ||
+                                          terminal->pvt->cursor.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK   
  ||
+                                          terminal->pvt->cursor.row > bbox_bottomright.y + 
VTE_CELL_BBOX_SLACK ||
+                                          terminal->pvt->cursor.row < bbox_topleft.y - 
VTE_CELL_BBOX_SLACK))) {
                                /* Clip off any part of the box which isn't already on-screen. */
                                bbox_topleft.x = MAX(bbox_topleft.x, 0);
                                bbox_topleft.y = MAX(bbox_topleft.y, delta);
@@ -3856,19 +3850,19 @@ skip_chunk:
                        }
 
                        bbox_topleft.x = MIN(bbox_topleft.x,
-                                       screen->cursor_current.col);
+                                        terminal->pvt->cursor.col);
                        bbox_topleft.y = MIN(bbox_topleft.y,
-                                       screen->cursor_current.row);
+                                        terminal->pvt->cursor.row);
 
                        /* Insert the character. */
                        if (G_UNLIKELY (_vte_terminal_insert_char(terminal, c,
                                                 FALSE, FALSE))) {
                                /* line wrapped, correct bbox */
                                if (invalidated_text &&
-                                               (screen->cursor_current.col > bbox_bottomright.x + 
VTE_CELL_BBOX_SLACK  ||
-                                                screen->cursor_current.col < bbox_topleft.x - 
VTE_CELL_BBOX_SLACK      ||
-                                                screen->cursor_current.row > bbox_bottomright.y + 
VTE_CELL_BBOX_SLACK  ||
-                                                screen->cursor_current.row < bbox_topleft.y - 
VTE_CELL_BBOX_SLACK)) {
+                                                (terminal->pvt->cursor.col > bbox_bottomright.x + 
VTE_CELL_BBOX_SLACK  ||
+                                                 terminal->pvt->cursor.col < bbox_topleft.x - 
VTE_CELL_BBOX_SLACK      ||
+                                                 terminal->pvt->cursor.row > bbox_bottomright.y + 
VTE_CELL_BBOX_SLACK  ||
+                                                 terminal->pvt->cursor.row < bbox_topleft.y - 
VTE_CELL_BBOX_SLACK)) {
                                        /* Clip off any part of the box which isn't already on-screen. */
                                        bbox_topleft.x = MAX(bbox_topleft.x, 0);
                                        bbox_topleft.y = MAX(bbox_topleft.y, delta);
@@ -3889,15 +3883,15 @@ skip_chunk:
                                }
                                bbox_topleft.x = MIN(bbox_topleft.x, 0);
                                bbox_topleft.y = MIN(bbox_topleft.y,
-                                               screen->cursor_current.row);
+                                                     terminal->pvt->cursor.row);
                        }
                        /* Add the cells over which we have moved to the region
                         * which we need to refresh for the user. */
                        bbox_bottomright.x = MAX(bbox_bottomright.x,
-                                       screen->cursor_current.col);
-                       /* cursor_current.row + 1 (defer until inv.) */
+                                                 terminal->pvt->cursor.col);
+                        /* cursor.row + 1 (defer until inv.) */
                        bbox_bottomright.y = MAX(bbox_bottomright.y,
-                                       screen->cursor_current.row);
+                                                 terminal->pvt->cursor.row);
                        invalidated_text = TRUE;
 
                        /* We *don't* emit flush pending signals here. */
@@ -3931,7 +3925,7 @@ skip_chunk:
                         _vte_ring_delta(screen->row_data));
                /* The cursor shouldn't be above or below the addressable
                 * part of the display buffer. */
-               g_assert(screen->cursor_current.row >= screen->insert_delta);
+                g_assert(terminal->pvt->cursor.row >= terminal->pvt->screen->insert_delta);
 #endif
 
 next_match:
@@ -4005,8 +3999,8 @@ next_match:
        }
 
 
-       if ((cursor.col != terminal->pvt->screen->cursor_current.col) ||
-           (cursor.row != terminal->pvt->screen->cursor_current.row)) {
+        if ((cursor.col != terminal->pvt->cursor.col) ||
+            (cursor.row != terminal->pvt->cursor.row)) {
                /* invalidate the old and new cursor positions */
                if (cursor_visible)
                        _vte_invalidate_cell(terminal, cursor.col, cursor.row);
@@ -4022,10 +4016,10 @@ next_match:
        /* Tell the input method where the cursor is. */
        if (gtk_widget_get_realized (&terminal->widget)) {
                GdkRectangle rect;
-               rect.x = terminal->pvt->screen->cursor_current.col *
+                rect.x = terminal->pvt->cursor.col *
                         terminal->pvt->char_width + terminal->pvt->padding.left;
                rect.width = terminal->pvt->char_width;
-               rect.y = (terminal->pvt->screen->cursor_current.row - delta) *
+                rect.y = (terminal->pvt->cursor.row - delta) *
                         terminal->pvt->char_height + terminal->pvt->padding.top;
                rect.height = terminal->pvt->char_height;
                gtk_im_context_set_cursor_location(terminal->pvt->im_context,
@@ -4483,8 +4477,8 @@ vte_terminal_feed_child_using_modes(VteTerminal *terminal,
        }
        if (length > 0) {
                vte_terminal_send(terminal, "UTF-8", data, length,
-                                 !terminal->pvt->screen->sendrecv_mode,
-                                 terminal->pvt->screen->linefeed_mode);
+                                  !terminal->pvt->sendrecv_mode,
+                                  terminal->pvt->linefeed_mode);
        }
 }
 
@@ -4746,7 +4740,7 @@ vte_terminal_key_press(GtkWidget *widget, GdkEventKey *event)
                /* If we're in margin bell mode and on the border of the
                 * margin, bell. */
                if (terminal->pvt->margin_bell) {
-                       if ((terminal->pvt->screen->cursor_current.col +
+                        if ((terminal->pvt->cursor.col +
                             (glong) terminal->pvt->bell_margin) ==
                             terminal->pvt->column_count) {
                                _vte_terminal_beep (terminal);
@@ -6163,10 +6157,10 @@ vte_terminal_get_cursor_position(VteTerminal *terminal,
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
        if (column) {
-               *column = terminal->pvt->screen->cursor_current.col;
+                *column = terminal->pvt->cursor.col;
        }
        if (row) {
-               *row = terminal->pvt->screen->cursor_current.row;
+                *row = terminal->pvt->cursor.row;
        }
 }
 
@@ -7657,37 +7651,35 @@ vte_terminal_screen_set_size(VteTerminal *terminal, VteScreen *screen, glong old
        _vte_debug_print(VTE_DEBUG_RESIZE,
                        "Resizing %s screen\n"
                        "Old  insert_delta=%ld  scroll_delta=%ld\n"
-                       "     cursor_current (absolute)  row=%ld  (visual line %ld)  col=%ld\n"
+                        "     cursor (absolute)  row=%ld  (visual line %ld)  col=%ld\n"
                        "     cursor_saved (relative to insert_delta)  row=%ld  col=%ld\n",
                        screen == &terminal->pvt->normal_screen ? "normal" : "alternate",
                        screen->insert_delta, screen->scroll_delta,
-                       screen->cursor_current.row, screen->cursor_current.row - screen->scroll_delta + 1, 
screen->cursor_current.col,
-                       screen->cursor_saved.row, screen->cursor_saved.col);
-
-       screen->scrolling_restricted = FALSE;
+                        terminal->pvt->cursor.row, terminal->pvt->cursor.row - screen->scroll_delta + 1, 
terminal->pvt->cursor.col,
+                        screen->saved.cursor.row, screen->saved.cursor.col);
 
-       cursor_saved_absolute.row = screen->cursor_saved.row + screen->insert_delta;
-       cursor_saved_absolute.col = screen->cursor_saved.col;
+        cursor_saved_absolute.row = screen->saved.cursor.row + screen->insert_delta;
+        cursor_saved_absolute.col = screen->saved.cursor.col;
        below_viewport.row = screen->scroll_delta + old_rows;
        below_viewport.col = 0;
-       below_current_paragraph.row = screen->cursor_current.row + 1;
+        below_current_paragraph.row = terminal->pvt->cursor.row + 1;
        while (below_current_paragraph.row < _vte_ring_next(ring)
            && _vte_ring_index(ring, below_current_paragraph.row - 1)->attr.soft_wrapped) {
                below_current_paragraph.row++;
        }
        below_current_paragraph.col = 0;
-       markers[0] = &screen->cursor_current;
-       markers[1] = &cursor_saved_absolute;
-       markers[2] = &below_viewport;
-       markers[3] = &below_current_paragraph;
-       if (screen == terminal->pvt->screen && terminal->pvt->has_selection) {
-               /* selection_end is inclusive, make it non-inclusive, see bug 722635. */
-               terminal->pvt->selection_end.col++;
-               markers[4] = &terminal->pvt->selection_start;
-               markers[5] = &terminal->pvt->selection_end;
-               markers[6] = NULL;
-       } else {
-               markers[4] = NULL;
+        memset(&markers, 0, sizeof(markers));
+        markers[0] = &cursor_saved_absolute;
+        markers[1] = &below_viewport;
+        markers[2] = &below_current_paragraph;
+        if (screen == terminal->pvt->screen)
+                /* Tracking the current cursor only makes sense on the active screen. */
+                markers[3] = &terminal->pvt->cursor;
+                if (terminal->pvt->has_selection) {
+                        /* selection_end is inclusive, make it non-inclusive, see bug 722635. */
+                        terminal->pvt->selection_end.col++;
+                        markers[4] = &terminal->pvt->selection_start;
+                        markers[5] = &terminal->pvt->selection_end;
        }
 
        old_top_lines = below_current_paragraph.row - screen->insert_delta;
@@ -7756,16 +7748,16 @@ vte_terminal_screen_set_size(VteTerminal *terminal, VteScreen *screen, glong old
 
        /* Don't clamp, they'll be clamped when restored. Until then remember off-screen values
           since they might become on-screen again on subsequent resizes. */
-       screen->cursor_saved.row = cursor_saved_absolute.row - screen->insert_delta;
-       screen->cursor_saved.col = cursor_saved_absolute.col;
+        screen->saved.cursor.row = cursor_saved_absolute.row - screen->insert_delta;
+        screen->saved.cursor.col = cursor_saved_absolute.col;
 
        _vte_debug_print(VTE_DEBUG_RESIZE,
                        "New  insert_delta=%ld  scroll_delta=%ld\n"
-                       "     cursor_current (absolute)  row=%ld  (visual line %ld)  col=%ld\n"
+                        "     cursor (absolute)  row=%ld  (visual line %ld)  col=%ld\n"
                        "     cursor_saved (relative to insert_delta)  row=%ld  col=%ld\n\n",
                        screen->insert_delta, new_scroll_delta,
-                       screen->cursor_current.row, screen->cursor_current.row - new_scroll_delta + 1, 
screen->cursor_current.col,
-                       screen->cursor_saved.row, screen->cursor_saved.col);
+                        terminal->pvt->cursor.row, terminal->pvt->cursor.row - new_scroll_delta + 1, 
terminal->pvt->cursor.col,
+                        screen->saved.cursor.row, screen->saved.cursor.col);
 
        if (screen == terminal->pvt->screen)
                vte_terminal_queue_adjustment_value_changed (
@@ -7787,7 +7779,6 @@ vte_terminal_screen_set_size(VteTerminal *terminal, VteScreen *screen, glong old
 void
 vte_terminal_set_size(VteTerminal *terminal, glong columns, glong rows)
 {
-       VteScreen *screen;
        glong old_columns, old_rows;
 
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
@@ -7815,6 +7806,8 @@ vte_terminal_set_size(VteTerminal *terminal, glong columns, glong rows)
                terminal->pvt->column_count = columns;
        }
        if (old_rows != terminal->pvt->row_count || old_columns != terminal->pvt->column_count) {
+                terminal->pvt->scrolling_restricted = FALSE;
+
                _vte_ring_set_visible_rows_hint(terminal->pvt->normal_screen.row_data, 
terminal->pvt->row_count);
                _vte_ring_set_visible_rows_hint(terminal->pvt->alternate_screen.row_data, 
terminal->pvt->row_count);
 
@@ -7828,16 +7821,10 @@ vte_terminal_set_size(VteTerminal *terminal, glong columns, glong rows)
                 vte_terminal_set_scrollback_lines(terminal,
                                                   terminal->pvt->scrollback_lines);
                 /* Ensure the cursor is valid */
-                screen = &terminal->pvt->normal_screen;
-                screen->cursor_current.row = CLAMP (screen->cursor_current.row,
-                                                    _vte_ring_delta (screen->row_data),
-                                                    MAX (_vte_ring_delta (screen->row_data),
-                                                         _vte_ring_next (screen->row_data) - 1));
-                screen = &terminal->pvt->alternate_screen;
-                screen->cursor_current.row = CLAMP (screen->cursor_current.row,
-                                                    _vte_ring_delta (screen->row_data),
-                                                    MAX (_vte_ring_delta (screen->row_data),
-                                                         _vte_ring_next (screen->row_data) - 1));
+                terminal->pvt->cursor.row = CLAMP (terminal->pvt->cursor.row,
+                                                    _vte_ring_delta (terminal->pvt->screen->row_data),
+                                                    MAX (_vte_ring_delta (terminal->pvt->screen->row_data),
+                                                         _vte_ring_next (terminal->pvt->screen->row_data) - 
1));
 
                _vte_terminal_adjust_adjustments_full (terminal);
                gtk_widget_queue_resize_no_redraw (&terminal->widget);
@@ -7990,12 +7977,10 @@ vte_terminal_init(VteTerminal *terminal)
 
        /* Initialize the screens and histories. */
        _vte_ring_init (pvt->alternate_screen.row_data, terminal->pvt->row_count);
-       pvt->alternate_screen.sendrecv_mode = TRUE;
        pvt->screen = &terminal->pvt->alternate_screen;
        _vte_terminal_set_default_attributes(terminal);
 
        _vte_ring_init (pvt->normal_screen.row_data,  VTE_SCROLLBACK_INIT);
-       pvt->normal_screen.sendrecv_mode = TRUE;
        pvt->screen = &terminal->pvt->normal_screen;
        _vte_terminal_set_default_attributes(terminal);
 
@@ -8026,8 +8011,12 @@ vte_terminal_init(VteTerminal *terminal)
        pvt->keypad_mode = VTE_KEYMODE_NORMAL;
        pvt->cursor_mode = VTE_KEYMODE_NORMAL;
         pvt->autowrap = TRUE;
+        pvt->sendrecv_mode = TRUE;
+        pvt->normal_screen.saved.sendrecv_mode = TRUE;
+        pvt->alternate_screen.saved.sendrecv_mode = TRUE;
        pvt->dec_saved = g_hash_table_new(NULL, NULL);
         pvt->matcher = _vte_matcher_new();
+        pvt->alternate_screen_scroll = TRUE;
 
        /* Setting the terminal type and size requires the PTY master to
         * be set up properly first. */
@@ -8087,8 +8076,6 @@ vte_terminal_init(VteTerminal *terminal)
         pvt->font_scale = 1.;
        pvt->has_fonts = FALSE;
 
-        pvt->alternate_screen_scroll = TRUE;
-
        /* Not all backends generate GdkVisibilityNotify, so mark the
         * window as unobscured initially. */
        pvt->visibility_state = GDK_VISIBILITY_UNOBSCURED;
@@ -8660,7 +8647,7 @@ vte_terminal_determine_colors_internal(VteTerminal *terminal,
        back = cell->attr.back;
 
        /* Reverse-mode switches default fore and back colors */
-       if (G_UNLIKELY (terminal->pvt->screen->reverse_mode)) {
+        if (G_UNLIKELY (terminal->pvt->reverse_mode)) {
                if (fore == VTE_DEFAULT_FG)
                        fore = VTE_DEFAULT_BG;
                if (back == VTE_DEFAULT_BG)
@@ -8965,8 +8952,8 @@ _vte_terminal_fudge_pango_colors(VteTerminal *terminal, GSList *attributes,
                                (props[i].bg.red == 0) &&
                                (props[i].bg.green == 0) &&
                                (props[i].bg.blue == 0)) {
-                       cells[i].attr.fore = terminal->pvt->screen->color_defaults.attr.fore;
-                       cells[i].attr.back = terminal->pvt->screen->color_defaults.attr.back;
+                        cells[i].attr.fore = terminal->pvt->color_defaults.attr.fore;
+                        cells[i].attr.back = terminal->pvt->color_defaults.attr.back;
                        cells[i].attr.reverse = TRUE;
                }
        }
@@ -9052,7 +9039,7 @@ _vte_terminal_translate_pango_cells(VteTerminal *terminal, PangoAttrList *attrs,
        guint i;
 
        for (i = 0; i < n_cells; i++) {
-               cells[i] = terminal->pvt->screen->fill_defaults;
+                cells[i] = terminal->pvt->fill_defaults;
        }
 
        attriter = pango_attr_list_get_iterator(attrs);
@@ -9548,8 +9535,8 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
 
        screen = terminal->pvt->screen;
        delta = screen->scroll_delta;
-       col = screen->cursor_current.col;
-       drow = screen->cursor_current.row;
+        col = terminal->pvt->cursor.col;
+        drow = terminal->pvt->cursor.row;
        row = drow - delta;
        width = terminal->pvt->char_width;
        height = terminal->pvt->char_height;
@@ -9689,7 +9676,7 @@ vte_terminal_paint_im_preedit_string(VteTerminal *terminal)
        height = terminal->pvt->char_height;
        delta = screen->scroll_delta;
 
-       row = screen->cursor_current.row - delta;
+        row = terminal->pvt->cursor.row - delta;
 
        /* Find out how many columns the pre-edit string takes up. */
        columns = vte_terminal_preedit_width(terminal, FALSE);
@@ -9697,7 +9684,7 @@ vte_terminal_paint_im_preedit_string(VteTerminal *terminal)
 
        /* If the pre-edit string won't fit on the screen if we start
         * drawing it at the cursor's position, move it left. */
-       col = screen->cursor_current.col;
+        col = terminal->pvt->cursor.col;
        if (col + columns > terminal->pvt->column_count) {
                col = MAX(0, terminal->pvt->column_count - columns);
        }
@@ -9723,8 +9710,8 @@ vte_terminal_paint_im_preedit_string(VteTerminal *terminal)
                                row * height + terminal->pvt->padding.top,
                                width * columns,
                                height);
-               fore = screen->color_defaults.attr.fore;
-               back = screen->color_defaults.attr.back;
+                fore = terminal->pvt->color_defaults.attr.fore;
+                back = terminal->pvt->color_defaults.attr.back;
                vte_terminal_draw_cells_with_attributes(terminal,
                                                        items, len,
                                                        terminal->pvt->im_preedit_attrs,
@@ -11603,7 +11590,7 @@ vte_terminal_set_scrollback_lines(VteTerminal *terminal, glong lines)
         /* The main screen gets the full scrollback buffer. */
         screen = &terminal->pvt->normal_screen;
         lines = MAX (lines, terminal->pvt->row_count);
-        next = MAX (screen->cursor_current.row + 1,
+        next = MAX (terminal->pvt->cursor.row + 1,
                     _vte_ring_next (screen->row_data));
         _vte_ring_resize (screen->row_data, lines);
         low = _vte_ring_delta (screen->row_data);
@@ -11808,18 +11795,16 @@ vte_terminal_reset(VteTerminal *terminal,
                _vte_ring_fini(pvt->alternate_screen.row_data);
                _vte_ring_init(pvt->alternate_screen.row_data, pvt->row_count);
                 _vte_ring_set_visible_rows_hint(pvt->alternate_screen.row_data, pvt->row_count);
-               pvt->normal_screen.cursor_saved.row = 0;
-               pvt->normal_screen.cursor_saved.col = 0;
-               pvt->normal_screen.cursor_current.row = 0;
-               pvt->normal_screen.cursor_current.col = 0;
+                pvt->normal_screen.saved.cursor.row = 0;
+                pvt->normal_screen.saved.cursor.col = 0;
                pvt->normal_screen.scroll_delta = 0;
                pvt->normal_screen.insert_delta = 0;
-               pvt->alternate_screen.cursor_saved.row = 0;
-               pvt->alternate_screen.cursor_saved.col = 0;
-               pvt->alternate_screen.cursor_current.row = 0;
-               pvt->alternate_screen.cursor_current.col = 0;
+                pvt->alternate_screen.saved.cursor.row = 0;
+                pvt->alternate_screen.saved.cursor.col = 0;
                pvt->alternate_screen.scroll_delta = 0;
                pvt->alternate_screen.insert_delta = 0;
+                pvt->cursor.row = 0;
+                pvt->cursor.col = 0;
                 /* Adjust the scrollbar to the new location. */
                 /* Hack: force a change in scroll_delta even if the value remains, so that
                    vte_term_q_adj_val_changed() doesn't shortcut to no-op, see bug 730599. */
@@ -11835,18 +11820,12 @@ vte_terminal_reset(VteTerminal *terminal,
        }
        /* Reset restricted scrolling regions, leave insert mode, make
         * the cursor visible again. */
-       pvt->normal_screen.scrolling_restricted = FALSE;
-       pvt->normal_screen.sendrecv_mode = TRUE;
-       pvt->normal_screen.insert_mode = FALSE;
-       pvt->normal_screen.linefeed_mode = FALSE;
-       pvt->normal_screen.origin_mode = FALSE;
-       pvt->normal_screen.reverse_mode = FALSE;
-       pvt->alternate_screen.scrolling_restricted = FALSE;
-       pvt->alternate_screen.sendrecv_mode = TRUE;
-       pvt->alternate_screen.insert_mode = FALSE;
-       pvt->alternate_screen.linefeed_mode = FALSE;
-       pvt->alternate_screen.origin_mode = FALSE;
-       pvt->alternate_screen.reverse_mode = FALSE;
+        pvt->scrolling_restricted = FALSE;
+        pvt->sendrecv_mode = TRUE;
+        pvt->insert_mode = FALSE;
+        pvt->linefeed_mode = FALSE;
+        pvt->origin_mode = FALSE;
+        pvt->reverse_mode = FALSE;
        pvt->cursor_visible = TRUE;
         /* For some reason, xterm doesn't reset alternateScroll, but we do. */
         pvt->alternate_screen_scroll = TRUE;
diff --git a/src/vteseq.c b/src/vteseq.c
index 1c0ddec..34b940a 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -261,8 +261,8 @@ vte_terminal_emit_resize_window(VteTerminal *terminal,
 static void
 _vte_terminal_ensure_cursor_is_onscreen (VteTerminal *terminal)
 {
-        if (G_UNLIKELY (terminal->pvt->screen->cursor_current.col >= terminal->pvt->column_count))
-                terminal->pvt->screen->cursor_current.col = terminal->pvt->column_count - 1;
+        if (G_UNLIKELY (terminal->pvt->cursor.col >= terminal->pvt->column_count))
+                terminal->pvt->cursor.col = terminal->pvt->column_count - 1;
 }
 
 static void
@@ -272,15 +272,15 @@ _vte_terminal_home_cursor (VteTerminal *terminal)
        VteScreen *screen;
        screen = terminal->pvt->screen;
 
-        if (screen->origin_mode &&
-            screen->scrolling_restricted) {
-                origin = screen->scrolling_region.start;
+        if (terminal->pvt->origin_mode &&
+            terminal->pvt->scrolling_restricted) {
+                origin = terminal->pvt->scrolling_region.start;
         } else {
                 origin = 0;
         }
 
-       screen->cursor_current.row = screen->insert_delta + origin;
-       screen->cursor_current.col = 0;
+        terminal->pvt->cursor.row = screen->insert_delta + origin;
+        terminal->pvt->cursor.col = 0;
 }
 
 /* Clear the entire screen. */
@@ -291,7 +291,7 @@ _vte_terminal_clear_screen (VteTerminal *terminal)
        VteScreen *screen;
        screen = terminal->pvt->screen;
        initial = screen->insert_delta;
-       row = screen->cursor_current.row - screen->insert_delta;
+        row = terminal->pvt->cursor.row - screen->insert_delta;
        initial = _vte_ring_next(screen->row_data);
        /* Add a new screen's worth of rows. */
        for (i = 0; i < terminal->pvt->row_count; i++)
@@ -299,7 +299,7 @@ _vte_terminal_clear_screen (VteTerminal *terminal)
        /* Move the cursor and insertion delta to the first line in the
         * newly-cleared area and scroll if need be. */
        screen->insert_delta = initial;
-       screen->cursor_current.row = row + screen->insert_delta;
+        terminal->pvt->cursor.row = row + screen->insert_delta;
        _vte_terminal_adjust_adjustments(terminal);
        /* Redraw everything. */
        _vte_invalidate_all(terminal);
@@ -318,19 +318,19 @@ _vte_terminal_clear_current_line (VteTerminal *terminal)
 
        /* If the cursor is actually on the screen, clear data in the row
         * which corresponds to the cursor. */
-       if (_vte_ring_next(screen->row_data) > screen->cursor_current.row) {
+        if (_vte_ring_next(screen->row_data) > terminal->pvt->cursor.row) {
                /* Get the data for the row which the cursor points to. */
-               rowdata = _vte_ring_index_writable (screen->row_data, screen->cursor_current.row);
+                rowdata = _vte_ring_index_writable (screen->row_data, terminal->pvt->cursor.row);
                g_assert(rowdata != NULL);
                /* Remove it. */
                _vte_row_data_shrink (rowdata, 0);
                /* Add enough cells to the end of the line to fill out the row. */
-               _vte_row_data_fill (rowdata, &screen->fill_defaults, terminal->pvt->column_count);
+                _vte_row_data_fill (rowdata, &terminal->pvt->fill_defaults, terminal->pvt->column_count);
                rowdata->attr.soft_wrapped = 0;
                /* Repaint this row. */
                _vte_invalidate_cells(terminal,
                                      0, terminal->pvt->column_count,
-                                     screen->cursor_current.row, 1);
+                                      terminal->pvt->cursor.row, 1);
        }
 
        /* We've modified the display.  Make a note of it. */
@@ -347,7 +347,7 @@ _vte_terminal_clear_above_current (VteTerminal *terminal)
        screen = terminal->pvt->screen;
        /* If the cursor is actually on the screen, clear data in the row
         * which corresponds to the cursor. */
-       for (i = screen->insert_delta; i < screen->cursor_current.row; i++) {
+        for (i = screen->insert_delta; i < terminal->pvt->cursor.row; i++) {
                if (_vte_ring_next(screen->row_data) > i) {
                        /* Get the data for the row we're erasing. */
                        rowdata = _vte_ring_index_writable (screen->row_data, i);
@@ -355,7 +355,7 @@ _vte_terminal_clear_above_current (VteTerminal *terminal)
                        /* Remove it. */
                        _vte_row_data_shrink (rowdata, 0);
                        /* Add new cells until we fill the row. */
-                       _vte_row_data_fill (rowdata, &screen->fill_defaults, terminal->pvt->column_count);
+                        _vte_row_data_fill (rowdata, &terminal->pvt->fill_defaults, 
terminal->pvt->column_count);
                        rowdata->attr.soft_wrapped = 0;
                        /* Repaint the row. */
                        _vte_invalidate_cells(terminal,
@@ -375,9 +375,9 @@ _vte_terminal_scroll_text (VteTerminal *terminal, int scroll_amount)
 
        screen = terminal->pvt->screen;
 
-       if (screen->scrolling_restricted) {
-               start = screen->insert_delta + screen->scrolling_region.start;
-               end = screen->insert_delta + screen->scrolling_region.end;
+        if (terminal->pvt->scrolling_restricted) {
+                start = screen->insert_delta + terminal->pvt->scrolling_region.start;
+                end = screen->insert_delta + terminal->pvt->scrolling_region.end;
        } else {
                start = screen->insert_delta;
                end = start + terminal->pvt->row_count - 1;
@@ -410,6 +410,96 @@ _vte_terminal_scroll_text (VteTerminal *terminal, int scroll_amount)
        terminal->pvt->text_deleted_flag = TRUE;
 }
 
+/* Restore cursor. */
+static void
+vte_sequence_handler_restore_cursor (VteTerminal *terminal, GValueArray *params)
+{
+        VteScreen *screen;
+        screen = terminal->pvt->screen;
+
+        terminal->pvt->cursor.col = screen->saved.cursor.col;
+        terminal->pvt->cursor.row = screen->insert_delta + CLAMP(screen->saved.cursor.row,
+                                                                 0, terminal->pvt->row_count - 1);
+        _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
+        terminal->pvt->reverse_mode = screen->saved.reverse_mode;
+        terminal->pvt->origin_mode = screen->saved.origin_mode;
+        terminal->pvt->sendrecv_mode = screen->saved.sendrecv_mode;
+        terminal->pvt->insert_mode = screen->saved.insert_mode;
+        terminal->pvt->linefeed_mode = screen->saved.linefeed_mode;
+        terminal->pvt->defaults = screen->saved.defaults;
+        terminal->pvt->color_defaults = screen->saved.color_defaults;
+        terminal->pvt->fill_defaults = screen->saved.fill_defaults;
+        terminal->pvt->character_replacements[0] = screen->saved.character_replacements[0];
+        terminal->pvt->character_replacements[1] = screen->saved.character_replacements[1];
+        terminal->pvt->character_replacement = screen->saved.character_replacement;
+}
+
+/* Save cursor. */
+static void
+vte_sequence_handler_save_cursor (VteTerminal *terminal, GValueArray *params)
+{
+        VteScreen *screen;
+        screen = terminal->pvt->screen;
+
+        screen->saved.cursor.col = terminal->pvt->cursor.col;
+        screen->saved.cursor.row = terminal->pvt->cursor.row - screen->insert_delta;
+
+        screen->saved.reverse_mode = terminal->pvt->reverse_mode;
+        screen->saved.origin_mode = terminal->pvt->origin_mode;
+        screen->saved.sendrecv_mode = terminal->pvt->sendrecv_mode;
+        screen->saved.insert_mode = terminal->pvt->insert_mode;
+        screen->saved.linefeed_mode = terminal->pvt->linefeed_mode;
+        screen->saved.defaults = terminal->pvt->defaults;
+        screen->saved.color_defaults = terminal->pvt->color_defaults;
+        screen->saved.fill_defaults = terminal->pvt->fill_defaults;
+        screen->saved.character_replacements[0] = terminal->pvt->character_replacements[0];
+        screen->saved.character_replacements[1] = terminal->pvt->character_replacements[1];
+        screen->saved.character_replacement = terminal->pvt->character_replacement;
+}
+
+/* Switch to normal screen. */
+static void
+vte_sequence_handler_normal_screen (VteTerminal *terminal, GValueArray *params)
+{
+        /* cursor.row includes insert_delta, adjust accordingly */
+        terminal->pvt->cursor.row -= terminal->pvt->screen->insert_delta;
+        terminal->pvt->screen = &terminal->pvt->normal_screen;
+        terminal->pvt->cursor.row += terminal->pvt->screen->insert_delta;
+
+        /* Make sure the ring is large enough */
+        _vte_terminal_ensure_row(terminal);
+}
+
+/* Switch to alternate screen. */
+static void
+vte_sequence_handler_alternate_screen (VteTerminal *terminal, GValueArray *params)
+{
+        /* cursor.row includes insert_delta, adjust accordingly */
+        terminal->pvt->cursor.row -= terminal->pvt->screen->insert_delta;
+        terminal->pvt->screen = &terminal->pvt->alternate_screen;
+        terminal->pvt->cursor.row += terminal->pvt->screen->insert_delta;
+
+        /* Make sure the ring is large enough */
+        _vte_terminal_ensure_row(terminal);
+}
+
+/* Switch to normal screen and restore cursor (in this order). */
+static void
+vte_sequence_handler_normal_screen_and_restore_cursor (VteTerminal *terminal, GValueArray *params)
+{
+        vte_sequence_handler_normal_screen (terminal, params);
+        vte_sequence_handler_restore_cursor (terminal, params);
+}
+
+/* Save cursor and switch to alternate screen (in this order). */
+static void
+vte_sequence_handler_save_cursor_and_alternate_screen (VteTerminal *terminal, GValueArray *params)
+{
+        vte_sequence_handler_save_cursor (terminal, params);
+        vte_sequence_handler_alternate_screen (terminal, params);
+}
+
 /* Set icon/window titles. */
 static void
 vte_sequence_handler_set_title_internal(VteTerminal *terminal,
@@ -478,13 +568,13 @@ vte_sequence_handler_set_mode_internal(VteTerminal *terminal,
        case 2:         /* keyboard action mode (?) */
                break;
        case 4:         /* insert/overtype mode */
-               terminal->pvt->screen->insert_mode = value;
+                terminal->pvt->insert_mode = value;
                break;
        case 12:        /* send/receive mode (local echo) */
-               terminal->pvt->screen->sendrecv_mode = value;
+                terminal->pvt->sendrecv_mode = value;
                break;
        case 20:        /* automatic newline / normal linefeed mode */
-               terminal->pvt->screen->linefeed_mode = value;
+                terminal->pvt->linefeed_mode = value;
                break;
        default:
                break;
@@ -534,7 +624,7 @@ vte_sequence_handler_multiple_r(VteTerminal *terminal,
                                 VteTerminalSequenceHandler handler)
 {
         vte_sequence_handler_multiple_limited(terminal, params, handler,
-                                              terminal->pvt->column_count - 
terminal->pvt->screen->cursor_current.col);
+                                              terminal->pvt->column_count - terminal->pvt->cursor.col);
 }
 
 static void
@@ -589,13 +679,13 @@ vte_sequence_handler_decset_internal(VteTerminal *terminal,
                  TRUE,
                  NULL, NULL,},
                /* 5: Reverse video. */
-               {5, SCREEN_OFFSET(reverse_mode), 0, 0,
+                {5, PRIV_OFFSET(reverse_mode), 0, 0,
                 FALSE,
                 TRUE,
                 NULL, NULL,},
                /* 6: Origin mode: when enabled, cursor positioning is
                 * relative to the scrolling region. */
-               {6, SCREEN_OFFSET(origin_mode), 0, 0,
+                {6, PRIV_OFFSET(origin_mode), 0, 0,
                 FALSE,
                 TRUE,
                 NULL, NULL,},
@@ -639,10 +729,11 @@ vte_sequence_handler_decset_internal(VteTerminal *terminal,
                 TRUE,
                 NULL, NULL,},
                /* 47: Alternate screen. */
-               {47, 0, 0, PRIV_OFFSET(screen),
-                PRIV_OFFSET(normal_screen),
-                 PRIV_OFFSET(alternate_screen),
-                NULL, NULL,},
+                {47, 0, 0, 0,
+                 0,
+                 0,
+                 vte_sequence_handler_normal_screen,
+                 vte_sequence_handler_alternate_screen,},
                /* 66: Keypad mode. */
                {66, PRIV_OFFSET(keypad_mode), 0, 0,
                 VTE_KEYMODE_NORMAL,
@@ -703,10 +794,11 @@ vte_sequence_handler_decset_internal(VteTerminal *terminal,
                /* 1037: disallowed, delete key policy is set by user. */
                {1037, 0, 0, 0, 0, 0, NULL, NULL,},
                /* 1047: Use alternate screen buffer. */
-               {1047, 0, 0, PRIV_OFFSET(screen),
-                PRIV_OFFSET(normal_screen),
-                PRIV_OFFSET(alternate_screen),
-                NULL, NULL,},
+                {1047, 0, 0, 0,
+                 0,
+                 0,
+                 vte_sequence_handler_normal_screen,
+                 vte_sequence_handler_alternate_screen,},
                /* 1048: Save/restore cursor position. */
                {1048, 0, 0, 0,
                 0,
@@ -715,11 +807,11 @@ vte_sequence_handler_decset_internal(VteTerminal *terminal,
                  vte_sequence_handler_save_cursor,},
                /* 1049: Use alternate screen buffer, saving the cursor
                 * position. */
-               {1049, 0, 0, PRIV_OFFSET(screen),
-                PRIV_OFFSET(normal_screen),
-                PRIV_OFFSET(alternate_screen),
-                 vte_sequence_handler_restore_cursor,
-                 vte_sequence_handler_save_cursor,},
+                {1049, 0, 0, 0,
+                 0,
+                 0,
+                 vte_sequence_handler_normal_screen_and_restore_cursor,
+                 vte_sequence_handler_save_cursor_and_alternate_screen,},
                /* 2004: Bracketed paste mode. */
                {2004, PRIV_OFFSET(bracketed_paste_mode), 0, 0,
                 FALSE,
@@ -847,12 +939,9 @@ vte_sequence_handler_decset_internal(VteTerminal *terminal,
        case 47:
        case 1047:
        case 1049:
-               /* Clear the alternate screen if we're switching
-                * to it, and home the cursor. */
+                /* Clear the alternate screen if we're switching to it */
                if (set) {
-                       _vte_terminal_set_default_attributes (terminal);
                        _vte_terminal_clear_screen (terminal);
-                       _vte_terminal_home_cursor (terminal);
                }
                /* Reset scrollbars and repaint everything. */
                gtk_adjustment_set_value(terminal->pvt->vadjustment,
@@ -957,7 +1046,7 @@ vte_sequence_handler_cursor_back_tab (VteTerminal *terminal, GValueArray *params
        long newcol;
 
        /* Calculate which column is the previous tab stop. */
-       newcol = terminal->pvt->screen->cursor_current.col;
+        newcol = terminal->pvt->cursor.col;
 
        if (terminal->pvt->tabstops != NULL) {
                /* Find the next tabstop. */
@@ -973,7 +1062,7 @@ vte_sequence_handler_cursor_back_tab (VteTerminal *terminal, GValueArray *params
        /* Warp the cursor. */
        _vte_debug_print(VTE_DEBUG_PARSE,
                        "Moving cursor to column %ld.\n", (long)newcol);
-       terminal->pvt->screen->cursor_current.col = newcol;
+        terminal->pvt->cursor.col = newcol;
 }
 
 /* Clear from the cursor position (inclusive!) to the beginning of the line. */
@@ -982,33 +1071,31 @@ _vte_sequence_handler_cb (VteTerminal *terminal, GValueArray *params)
 {
        VteRowData *rowdata;
        long i;
-       VteScreen *screen;
        VteCell *pcell;
-       screen = terminal->pvt->screen;
 
         _vte_terminal_ensure_cursor_is_onscreen(terminal);
 
        /* Get the data for the row which the cursor points to. */
        rowdata = _vte_terminal_ensure_row(terminal);
         /* Clean up Tab/CJK fragments. */
-        _vte_terminal_cleanup_fragments (terminal, 0, screen->cursor_current.col + 1);
+        _vte_terminal_cleanup_fragments (terminal, 0, terminal->pvt->cursor.col + 1);
        /* Clear the data up to the current column with the default
         * attributes.  If there is no such character cell, we need
         * to add one. */
-       for (i = 0; i <= screen->cursor_current.col; i++) {
+        for (i = 0; i <= terminal->pvt->cursor.col; i++) {
                if (i < (glong) _vte_row_data_length (rowdata)) {
                        /* Muck with the cell in this location. */
                        pcell = _vte_row_data_get_writable (rowdata, i);
-                       *pcell = screen->color_defaults;
+                        *pcell = terminal->pvt->color_defaults;
                } else {
                        /* Add new cells until we have one here. */
-                       _vte_row_data_append (rowdata, &screen->color_defaults);
+                        _vte_row_data_append (rowdata, &terminal->pvt->color_defaults);
                }
        }
        /* Repaint this row. */
        _vte_invalidate_cells(terminal,
-                             0, screen->cursor_current.col+1,
-                             screen->cursor_current.row, 1);
+                              0, terminal->pvt->cursor.col+1,
+                              terminal->pvt->cursor.row, 1);
 
        /* We've modified the display.  Make a note of it. */
        terminal->pvt->text_deleted_flag = TRUE;
@@ -1027,19 +1114,19 @@ _vte_sequence_handler_cd (VteTerminal *terminal, GValueArray *params)
        screen = terminal->pvt->screen;
        /* If the cursor is actually on the screen, clear the rest of the
         * row the cursor is on and all of the rows below the cursor. */
-       i = screen->cursor_current.row;
+        i = terminal->pvt->cursor.row;
        if (i < _vte_ring_next(screen->row_data)) {
                /* Get the data for the row we're clipping. */
                rowdata = _vte_ring_index_writable (screen->row_data, i);
                 /* Clean up Tab/CJK fragments. */
-                if ((glong) _vte_row_data_length (rowdata) > screen->cursor_current.col)
-                        _vte_terminal_cleanup_fragments (terminal, screen->cursor_current.col, 
_vte_row_data_length (rowdata));
+                if ((glong) _vte_row_data_length (rowdata) > terminal->pvt->cursor.col)
+                        _vte_terminal_cleanup_fragments (terminal, terminal->pvt->cursor.col, 
_vte_row_data_length (rowdata));
                /* Clear everything to the right of the cursor. */
                if (rowdata)
-                       _vte_row_data_shrink (rowdata, screen->cursor_current.col);
+                        _vte_row_data_shrink (rowdata, terminal->pvt->cursor.col);
        }
        /* Now for the rest of the lines. */
-       for (i = screen->cursor_current.row + 1;
+        for (i = terminal->pvt->cursor.row + 1;
             i < _vte_ring_next(screen->row_data);
             i++) {
                /* Get the data for the row we're removing. */
@@ -1049,7 +1136,7 @@ _vte_sequence_handler_cd (VteTerminal *terminal, GValueArray *params)
                        _vte_row_data_shrink (rowdata, 0);
        }
        /* Now fill the cleared areas. */
-       for (i = screen->cursor_current.row;
+        for (i = terminal->pvt->cursor.row;
             i < screen->insert_delta + terminal->pvt->row_count;
             i++) {
                /* Retrieve the row's data, creating it if necessary. */
@@ -1060,8 +1147,8 @@ _vte_sequence_handler_cd (VteTerminal *terminal, GValueArray *params)
                        rowdata = _vte_terminal_ring_append (terminal, FALSE);
                }
                /* Pad out the row. */
-               if (screen->fill_defaults.attr.back != VTE_DEFAULT_BG) {
-                       _vte_row_data_fill (rowdata, &screen->fill_defaults, terminal->pvt->column_count);
+                if (terminal->pvt->fill_defaults.attr.back != VTE_DEFAULT_BG) {
+                        _vte_row_data_fill (rowdata, &terminal->pvt->fill_defaults, 
terminal->pvt->column_count);
                }
                rowdata->attr.soft_wrapped = 0;
                /* Repaint this row. */
@@ -1079,46 +1166,41 @@ static void
 _vte_sequence_handler_ce (VteTerminal *terminal, GValueArray *params)
 {
        VteRowData *rowdata;
-       VteScreen *screen;
 
         _vte_terminal_ensure_cursor_is_onscreen(terminal);
 
-       screen = terminal->pvt->screen;
        /* Get the data for the row which the cursor points to. */
        rowdata = _vte_terminal_ensure_row(terminal);
        g_assert(rowdata != NULL);
-       if ((glong) _vte_row_data_length (rowdata) > screen->cursor_current.col) {
+        if ((glong) _vte_row_data_length (rowdata) > terminal->pvt->cursor.col) {
                 /* Clean up Tab/CJK fragments. */
-                _vte_terminal_cleanup_fragments (terminal, screen->cursor_current.col, _vte_row_data_length 
(rowdata));
+                _vte_terminal_cleanup_fragments (terminal, terminal->pvt->cursor.col, _vte_row_data_length 
(rowdata));
                 /* Remove the data at the end of the array until the current column
                  * is the end of the array. */
-               _vte_row_data_shrink (rowdata, screen->cursor_current.col);
+                _vte_row_data_shrink (rowdata, terminal->pvt->cursor.col);
                /* We've modified the display.  Make a note of it. */
                terminal->pvt->text_deleted_flag = TRUE;
        }
-       if (screen->fill_defaults.attr.back != VTE_DEFAULT_BG) {
+        if (terminal->pvt->fill_defaults.attr.back != VTE_DEFAULT_BG) {
                /* Add enough cells to fill out the row. */
-               _vte_row_data_fill (rowdata, &screen->fill_defaults, terminal->pvt->column_count);
+                _vte_row_data_fill (rowdata, &terminal->pvt->fill_defaults, terminal->pvt->column_count);
        }
        rowdata->attr.soft_wrapped = 0;
        /* Repaint this row. */
        _vte_invalidate_cells(terminal,
-                             screen->cursor_current.col,
+                              terminal->pvt->cursor.col,
                              terminal->pvt->column_count -
-                             screen->cursor_current.col,
-                             screen->cursor_current.row, 1);
+                              terminal->pvt->cursor.col,
+                              terminal->pvt->cursor.row, 1);
 }
 
 /* Move the cursor to the given column (horizontal position), 1-based. */
 static void
 vte_sequence_handler_cursor_character_absolute (VteTerminal *terminal, GValueArray *params)
 {
-       VteScreen *screen;
        GValue *value;
        long val;
 
-       screen = terminal->pvt->screen;
-
         val = 0;
        if ((params != NULL) && (params->n_values > 0)) {
                value = g_value_array_get_nth(params, 0);
@@ -1129,7 +1211,7 @@ vte_sequence_handler_cursor_character_absolute (VteTerminal *terminal, GValueArr
                }
        }
 
-        screen->cursor_current.col = val;
+        terminal->pvt->cursor.col = val;
 }
 
 /* Move the cursor to the given position, 1-based. */
@@ -1148,10 +1230,10 @@ vte_sequence_handler_cursor_position (VteTerminal *terminal, GValueArray *params
                /* The first is the row, the second is the column. */
                row = g_value_array_get_nth(params, 0);
                if (G_VALUE_HOLDS_LONG(row)) {
-                       if (screen->origin_mode &&
-                           screen->scrolling_restricted) {
-                               origin = screen->scrolling_region.start;
-                                rowmax = screen->scrolling_region.end;
+                        if (terminal->pvt->origin_mode &&
+                            terminal->pvt->scrolling_restricted) {
+                                origin = terminal->pvt->scrolling_region.start;
+                                rowmax = terminal->pvt->scrolling_region.end;
                        } else {
                                origin = 0;
                                 rowmax = terminal->pvt->row_count - 1;
@@ -1167,15 +1249,15 @@ vte_sequence_handler_cursor_position (VteTerminal *terminal, GValueArray *params
                        }
                }
        }
-       screen->cursor_current.row = rowval + screen->insert_delta;
-       screen->cursor_current.col = colval;
+        terminal->pvt->cursor.row = rowval + screen->insert_delta;
+        terminal->pvt->cursor.col = colval;
 }
 
 /* Carriage return. */
 static void
 vte_sequence_handler_carriage_return (VteTerminal *terminal, GValueArray *params)
 {
-       terminal->pvt->screen->cursor_current.col = 0;
+        terminal->pvt->cursor.col = 0;
 }
 
 /* Restrict scrolling and updates to a subset of the visible lines. */
@@ -1189,7 +1271,7 @@ vte_sequence_handler_set_scrolling_region (VteTerminal *terminal, GValueArray *p
        /* We require two parameters.  Anything less is a reset. */
        screen = terminal->pvt->screen;
        if ((params == NULL) || (params->n_values < 2)) {
-               screen->scrolling_restricted = FALSE;
+                terminal->pvt->scrolling_restricted = FALSE;
                 _vte_terminal_home_cursor (terminal);
                return;
        }
@@ -1219,13 +1301,13 @@ vte_sequence_handler_set_scrolling_region (VteTerminal *terminal, GValueArray *p
        }
 
        /* Set the right values. */
-       screen->scrolling_region.start = start;
-       screen->scrolling_region.end = end;
-       screen->scrolling_restricted = TRUE;
-       if (screen->scrolling_region.start == 0 &&
-           screen->scrolling_region.end == rows - 1) {
+        terminal->pvt->scrolling_region.start = start;
+        terminal->pvt->scrolling_region.end = end;
+        terminal->pvt->scrolling_restricted = TRUE;
+        if (terminal->pvt->scrolling_region.start == 0 &&
+            terminal->pvt->scrolling_region.end == rows - 1) {
                /* Special case -- run wild, run free. */
-               screen->scrolling_restricted = FALSE;
+                terminal->pvt->scrolling_restricted = FALSE;
        } else {
                /* Maybe extend the ring -- bug 710483 */
                while (_vte_ring_next(screen->row_data) < screen->insert_delta + rows)
@@ -1239,7 +1321,7 @@ vte_sequence_handler_set_scrolling_region (VteTerminal *terminal, GValueArray *p
 static void
 vte_sequence_handler_cursor_next_line (VteTerminal *terminal, GValueArray *params)
 {
-       terminal->pvt->screen->cursor_current.col = 0;
+        terminal->pvt->cursor.col = 0;
         vte_sequence_handler_cursor_down (terminal, params);
 }
 
@@ -1247,7 +1329,7 @@ vte_sequence_handler_cursor_next_line (VteTerminal *terminal, GValueArray *param
 static void
 vte_sequence_handler_cursor_preceding_line (VteTerminal *terminal, GValueArray *params)
 {
-       terminal->pvt->screen->cursor_current.col = 0;
+        terminal->pvt->cursor.col = 0;
         vte_sequence_handler_cursor_up (terminal, params);
 }
 
@@ -1269,17 +1351,17 @@ vte_sequence_handler_line_position_absolute (VteTerminal *terminal, GValueArray
                }
        }
 
-        if (screen->origin_mode &&
-            screen->scrolling_restricted) {
-                origin = screen->scrolling_region.start;
-                rowmax = screen->scrolling_region.end;
+        if (terminal->pvt->origin_mode &&
+            terminal->pvt->scrolling_restricted) {
+                origin = terminal->pvt->scrolling_region.start;
+                rowmax = terminal->pvt->scrolling_region.end;
         } else {
                 origin = 0;
                 rowmax = terminal->pvt->row_count - 1;
         }
         val = val - 1 + origin;
         val = CLAMP(val, origin, rowmax);
-        screen->cursor_current.row = screen->insert_delta + val;
+        terminal->pvt->cursor.row = screen->insert_delta + val;
 }
 
 /* Delete a character at the current cursor position. */
@@ -1294,26 +1376,26 @@ _vte_sequence_handler_dc (VteTerminal *terminal, GValueArray *params)
 
        screen = terminal->pvt->screen;
 
-       if (_vte_ring_next(screen->row_data) > screen->cursor_current.row) {
+        if (_vte_ring_next(screen->row_data) > terminal->pvt->cursor.row) {
                long len;
                /* Get the data for the row which the cursor points to. */
-               rowdata = _vte_ring_index_writable (screen->row_data, screen->cursor_current.row);
+                rowdata = _vte_ring_index_writable (screen->row_data, terminal->pvt->cursor.row);
                g_assert(rowdata != NULL);
-               col = screen->cursor_current.col;
+                col = terminal->pvt->cursor.col;
                len = _vte_row_data_length (rowdata);
                /* Remove the column. */
                if (col < len) {
                         /* Clean up Tab/CJK fragments. */
                         _vte_terminal_cleanup_fragments (terminal, col, col + 1);
                        _vte_row_data_remove (rowdata, col);
-                       if (screen->fill_defaults.attr.back != VTE_DEFAULT_BG) {
-                               _vte_row_data_fill (rowdata, &screen->fill_defaults, 
terminal->pvt->column_count);
+                        if (terminal->pvt->fill_defaults.attr.back != VTE_DEFAULT_BG) {
+                                _vte_row_data_fill (rowdata, &terminal->pvt->fill_defaults, 
terminal->pvt->column_count);
                                len = terminal->pvt->column_count;
                        }
                        /* Repaint this row. */
                        _vte_invalidate_cells(terminal,
                                        col, len - col,
-                                       screen->cursor_current.row, 1);
+                                        terminal->pvt->cursor.row, 1);
                }
        }
 
@@ -1341,8 +1423,8 @@ vte_sequence_handler_cursor_down (VteTerminal *terminal, GValueArray *params)
 
        screen = terminal->pvt->screen;
 
-       if (screen->scrolling_restricted) {
-               end = screen->insert_delta + screen->scrolling_region.end;
+        if (terminal->pvt->scrolling_restricted) {
+                end = screen->insert_delta + terminal->pvt->scrolling_region.end;
        } else {
                 end = screen->insert_delta + terminal->pvt->row_count - 1;
        }
@@ -1356,7 +1438,7 @@ vte_sequence_handler_cursor_down (VteTerminal *terminal, GValueArray *params)
                 }
         }
 
-        screen->cursor_current.row = MIN(screen->cursor_current.row + val, end);
+        terminal->pvt->cursor.row = MIN(terminal->pvt->cursor.row + val, end);
 }
 
 /* Erase characters starting at the cursor position (overwriting N with
@@ -1385,30 +1467,30 @@ vte_sequence_handler_erase_characters (VteTerminal *terminal, GValueArray *param
 
        /* Clear out the given number of characters. */
        rowdata = _vte_terminal_ensure_row(terminal);
-       if (_vte_ring_next(screen->row_data) > screen->cursor_current.row) {
+        if (_vte_ring_next(screen->row_data) > terminal->pvt->cursor.row) {
                g_assert(rowdata != NULL);
                 /* Clean up Tab/CJK fragments. */
-                _vte_terminal_cleanup_fragments (terminal, screen->cursor_current.col, 
screen->cursor_current.col + count);
+                _vte_terminal_cleanup_fragments (terminal, terminal->pvt->cursor.col, 
terminal->pvt->cursor.col + count);
                /* Write over the characters.  (If there aren't enough, we'll
                 * need to create them.) */
                for (i = 0; i < count; i++) {
-                       col = screen->cursor_current.col + i;
+                        col = terminal->pvt->cursor.col + i;
                        if (col >= 0) {
                                if (col < (glong) _vte_row_data_length (rowdata)) {
                                        /* Replace this cell with the current
                                         * defaults. */
                                        cell = _vte_row_data_get_writable (rowdata, col);
-                                       *cell = screen->color_defaults;
+                                        *cell = terminal->pvt->color_defaults;
                                } else {
                                        /* Add new cells until we have one here. */
-                                       _vte_row_data_fill (rowdata, &screen->color_defaults, col + 1);
+                                        _vte_row_data_fill (rowdata, &terminal->pvt->color_defaults, col + 
1);
                                }
                        }
                }
                /* Repaint this row. */
                _vte_invalidate_cells(terminal,
-                                     screen->cursor_current.col, count,
-                                     screen->cursor_current.row, 1);
+                                      terminal->pvt->cursor.col, count,
+                                      terminal->pvt->cursor.row, 1);
        }
 
        /* We've modified the display.  Make a note of it. */
@@ -1427,17 +1509,14 @@ static void
 _vte_sequence_handler_insert_character (VteTerminal *terminal, GValueArray *params)
 {
        VteVisualPosition save;
-       VteScreen *screen;
 
         _vte_terminal_ensure_cursor_is_onscreen(terminal);
 
-       screen = terminal->pvt->screen;
-
-       save = screen->cursor_current;
+        save = terminal->pvt->cursor;
 
        _vte_terminal_insert_char(terminal, ' ', TRUE, TRUE);
 
-       screen->cursor_current = save;
+        terminal->pvt->cursor = save;
 }
 
 /* Insert N blank characters. */
@@ -1459,14 +1538,11 @@ vte_sequence_handler_index (VteTerminal *terminal, GValueArray *params)
 static void
 vte_sequence_handler_backspace (VteTerminal *terminal, GValueArray *params)
 {
-       VteScreen *screen;
-
         _vte_terminal_ensure_cursor_is_onscreen(terminal);
 
-       screen = terminal->pvt->screen;
-       if (screen->cursor_current.col > 0) {
+        if (terminal->pvt->cursor.col > 0) {
                /* There's room to move left, so do so. */
-               screen->cursor_current.col--;
+                terminal->pvt->cursor.col--;
        }
 }
 
@@ -1474,14 +1550,11 @@ vte_sequence_handler_backspace (VteTerminal *terminal, GValueArray *params)
 static void
 vte_sequence_handler_cursor_backward (VteTerminal *terminal, GValueArray *params)
 {
-       VteScreen *screen;
         GValue *value;
         long val;
 
         _vte_terminal_ensure_cursor_is_onscreen(terminal);
 
-        screen = terminal->pvt->screen;
-
         val = 1;
         if (params != NULL && params->n_values >= 1) {
                 value = g_value_array_get_nth(params, 0);
@@ -1489,21 +1562,18 @@ vte_sequence_handler_cursor_backward (VteTerminal *terminal, GValueArray *params
                         val = MAX(g_value_get_long(value), 1);
                 }
         }
-        screen->cursor_current.col = MAX(screen->cursor_current.col - val, 0);
+        terminal->pvt->cursor.col = MAX(terminal->pvt->cursor.col - val, 0);
 }
 
 /* Cursor right N columns. */
 static void
 vte_sequence_handler_cursor_forward (VteTerminal *terminal, GValueArray *params)
 {
-       VteScreen *screen;
         GValue *value;
         long val;
 
         _vte_terminal_ensure_cursor_is_onscreen(terminal);
 
-       screen = terminal->pvt->screen;
-
         val = 1;
         if (params != NULL && params->n_values >= 1) {
                 value = g_value_array_get_nth(params, 0);
@@ -1513,10 +1583,10 @@ vte_sequence_handler_cursor_forward (VteTerminal *terminal, GValueArray *params)
                 }
         }
         /* The cursor can be further to the right, don't move in that case. */
-        if (screen->cursor_current.col < terminal->pvt->column_count) {
+        if (terminal->pvt->cursor.col < terminal->pvt->column_count) {
                /* There's room to move right. */
-                screen->cursor_current.col = MIN(screen->cursor_current.col + val,
-                                                 terminal->pvt->column_count - 1);
+                terminal->pvt->cursor.col = MIN(terminal->pvt->cursor.col + val,
+                                                terminal->pvt->column_count - 1);
        }
 }
 
@@ -1524,7 +1594,7 @@ vte_sequence_handler_cursor_forward (VteTerminal *terminal, GValueArray *params)
 static void
 vte_sequence_handler_next_line (VteTerminal *terminal, GValueArray *params)
 {
-       terminal->pvt->screen->cursor_current.col = 0;
+        terminal->pvt->cursor.col = 0;
        _vte_terminal_cursor_down (terminal);
 }
 
@@ -1534,34 +1604,6 @@ vte_sequence_handler_linux_console_cursor_attributes (VteTerminal *terminal, GVa
 {
 }
 
-/* Restore cursor (position). */
-static void
-vte_sequence_handler_restore_cursor (VteTerminal *terminal, GValueArray *params)
-{
-       VteScreen *screen;
-       screen = terminal->pvt->screen;
-       screen->cursor_current.col = screen->cursor_saved.col;
-       screen->cursor_current.row = CLAMP(screen->cursor_saved.row +
-                                          screen->insert_delta,
-                                          screen->insert_delta,
-                                          screen->insert_delta +
-                                          terminal->pvt->row_count - 1);
-
-        _vte_terminal_ensure_cursor_is_onscreen(terminal);
-}
-
-/* Save cursor (position). */
-static void
-vte_sequence_handler_save_cursor (VteTerminal *terminal, GValueArray *params)
-{
-       VteScreen *screen;
-       screen = terminal->pvt->screen;
-       screen->cursor_saved.col = screen->cursor_current.col;
-       screen->cursor_saved.row = CLAMP(screen->cursor_current.row -
-                                        screen->insert_delta,
-                                        0, terminal->pvt->row_count - 1);
-}
-
 /* Scroll the text down N lines, but don't move the cursor. */
 static void
 vte_sequence_handler_scroll_down (VteTerminal *terminal, GValueArray *params)
@@ -1718,15 +1760,15 @@ vte_sequence_handler_reverse_index (VteTerminal *terminal, GValueArray *params)
 
        screen = terminal->pvt->screen;
 
-       if (screen->scrolling_restricted) {
-               start = screen->scrolling_region.start + screen->insert_delta;
-               end = screen->scrolling_region.end + screen->insert_delta;
+        if (terminal->pvt->scrolling_restricted) {
+                start = terminal->pvt->scrolling_region.start + screen->insert_delta;
+                end = terminal->pvt->scrolling_region.end + screen->insert_delta;
        } else {
                start = terminal->pvt->screen->insert_delta;
                end = start + terminal->pvt->row_count - 1;
        }
 
-       if (screen->cursor_current.row == start) {
+        if (terminal->pvt->cursor.row == start) {
                /* If we're at the top of the scrolling region, add a
                 * line at the top to scroll the bottom off. */
                _vte_terminal_ring_remove (terminal, end);
@@ -1738,7 +1780,7 @@ vte_sequence_handler_reverse_index (VteTerminal *terminal, GValueArray *params)
                                      start, 2);
        } else {
                /* Otherwise, just move the cursor up. */
-               screen->cursor_current.row--;
+                terminal->pvt->cursor.row--;
        }
        /* Adjust the scrollbars if necessary. */
        _vte_terminal_adjust_adjustments(terminal);
@@ -1754,19 +1796,17 @@ vte_sequence_handler_tab_set (VteTerminal *terminal, GValueArray *params)
                terminal->pvt->tabstops = g_hash_table_new(NULL, NULL);
        }
        _vte_terminal_set_tabstop(terminal,
-                                terminal->pvt->screen->cursor_current.col);
+                                 terminal->pvt->cursor.col);
 }
 
 /* Tab. */
 static void
 vte_sequence_handler_tab (VteTerminal *terminal, GValueArray *params)
 {
-       VteScreen *screen;
        long old_len, newcol, col;
 
        /* Calculate which column is the next tab stop. */
-       screen = terminal->pvt->screen;
-       newcol = col = screen->cursor_current.col;
+        newcol = col = terminal->pvt->cursor.col;
 
        g_assert (col >= 0);
 
@@ -1801,7 +1841,7 @@ vte_sequence_handler_tab (VteTerminal *terminal, GValueArray *params)
                 */
 
                old_len = _vte_row_data_length (rowdata);
-               _vte_row_data_fill (rowdata, &screen->fill_defaults, newcol);
+                _vte_row_data_fill (rowdata, &terminal->pvt->fill_defaults, newcol);
 
                /* Insert smart tab if there's nothing in the line after
                 * us.  Though, there may be empty cells (with non-default
@@ -1838,10 +1878,10 @@ vte_sequence_handler_tab (VteTerminal *terminal, GValueArray *params)
                }
 
                _vte_invalidate_cells (terminal,
-                               screen->cursor_current.col,
-                               newcol - screen->cursor_current.col,
-                               screen->cursor_current.row, 1);
-               screen->cursor_current.col = newcol;
+                                terminal->pvt->cursor.col,
+                                newcol - terminal->pvt->cursor.col,
+                                terminal->pvt->cursor.row, 1);
+                terminal->pvt->cursor.col = newcol;
        }
 }
 
@@ -1866,7 +1906,7 @@ vte_sequence_handler_tab_clear (VteTerminal *terminal, GValueArray *params)
        }
        if (param == 0) {
                _vte_terminal_clear_tabstop(terminal,
-                                          terminal->pvt->screen->cursor_current.col);
+                                           terminal->pvt->cursor.col);
        } else
        if (param == 3) {
                if (terminal->pvt->tabstops != NULL) {
@@ -1889,8 +1929,8 @@ vte_sequence_handler_cursor_up (VteTerminal *terminal, GValueArray *params)
 
        screen = terminal->pvt->screen;
 
-       if (screen->scrolling_restricted) {
-               start = screen->insert_delta + screen->scrolling_region.start;
+        if (terminal->pvt->scrolling_restricted) {
+                start = screen->insert_delta + terminal->pvt->scrolling_region.start;
        } else {
                start = screen->insert_delta;
        }
@@ -1904,7 +1944,7 @@ vte_sequence_handler_cursor_up (VteTerminal *terminal, GValueArray *params)
                 }
         }
 
-        screen->cursor_current.row = MAX(screen->cursor_current.row - val, start);
+        terminal->pvt->cursor.row = MAX(terminal->pvt->cursor.row - val, start);
 }
 
 /* Vertical tab. */
@@ -1994,9 +2034,9 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                                continue;
                        if (G_LIKELY (color != -1)) {
                                if (param0 == 38) {
-                                       terminal->pvt->screen->defaults.attr.fore = color;
+                                        terminal->pvt->defaults.attr.fore = color;
                                } else {
-                                       terminal->pvt->screen->defaults.attr.back = color;
+                                        terminal->pvt->defaults.attr.back = color;
                                }
                        }
                        continue;
@@ -2011,51 +2051,51 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                        _vte_terminal_set_default_attributes(terminal);
                        break;
                case 1:
-                       terminal->pvt->screen->defaults.attr.bold = 1;
+                        terminal->pvt->defaults.attr.bold = 1;
                        break;
                case 2:
-                       terminal->pvt->screen->defaults.attr.dim = 1;
+                        terminal->pvt->defaults.attr.dim = 1;
                        break;
                case 3:
-                       terminal->pvt->screen->defaults.attr.italic = 1;
+                        terminal->pvt->defaults.attr.italic = 1;
                        break;
                case 4:
-                       terminal->pvt->screen->defaults.attr.underline = 1;
+                        terminal->pvt->defaults.attr.underline = 1;
                        break;
                case 5:
-                       terminal->pvt->screen->defaults.attr.blink = 1;
+                        terminal->pvt->defaults.attr.blink = 1;
                        break;
                case 7:
-                       terminal->pvt->screen->defaults.attr.reverse = 1;
+                        terminal->pvt->defaults.attr.reverse = 1;
                        break;
                case 8:
-                       terminal->pvt->screen->defaults.attr.invisible = 1;
+                        terminal->pvt->defaults.attr.invisible = 1;
                        break;
                case 9:
-                       terminal->pvt->screen->defaults.attr.strikethrough = 1;
+                        terminal->pvt->defaults.attr.strikethrough = 1;
                        break;
                case 21: /* Error in old versions of linux console. */
                case 22: /* ECMA 48. */
-                       terminal->pvt->screen->defaults.attr.bold = 0;
-                       terminal->pvt->screen->defaults.attr.dim = 0;
+                        terminal->pvt->defaults.attr.bold = 0;
+                        terminal->pvt->defaults.attr.dim = 0;
                        break;
                case 23:
-                       terminal->pvt->screen->defaults.attr.italic = 0;
+                        terminal->pvt->defaults.attr.italic = 0;
                        break;
                case 24:
-                       terminal->pvt->screen->defaults.attr.underline = 0;
+                        terminal->pvt->defaults.attr.underline = 0;
                        break;
                case 25:
-                       terminal->pvt->screen->defaults.attr.blink = 0;
+                        terminal->pvt->defaults.attr.blink = 0;
                        break;
                case 27:
-                       terminal->pvt->screen->defaults.attr.reverse = 0;
+                        terminal->pvt->defaults.attr.reverse = 0;
                        break;
                case 28:
-                       terminal->pvt->screen->defaults.attr.invisible = 0;
+                        terminal->pvt->defaults.attr.invisible = 0;
                        break;
                case 29:
-                       terminal->pvt->screen->defaults.attr.strikethrough = 0;
+                        terminal->pvt->defaults.attr.strikethrough = 0;
                        break;
                case 30:
                case 31:
@@ -2065,7 +2105,7 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                case 35:
                case 36:
                case 37:
-                       terminal->pvt->screen->defaults.attr.fore = VTE_LEGACY_COLORS_OFFSET + param - 30;
+                        terminal->pvt->defaults.attr.fore = VTE_LEGACY_COLORS_OFFSET + param - 30;
                        break;
                case 38:
                case 48:
@@ -2101,9 +2141,9 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                                }
                                if (G_LIKELY (color != -1)) {
                                        if (param == 38) {
-                                               terminal->pvt->screen->defaults.attr.fore = color;
+                                                terminal->pvt->defaults.attr.fore = color;
                                        } else {
-                                               terminal->pvt->screen->defaults.attr.back = color;
+                                                terminal->pvt->defaults.attr.back = color;
                                        }
                                }
                        }
@@ -2111,7 +2151,7 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                }
                case 39:
                        /* default foreground */
-                       terminal->pvt->screen->defaults.attr.fore = VTE_DEFAULT_FG;
+                        terminal->pvt->defaults.attr.fore = VTE_DEFAULT_FG;
                        break;
                case 40:
                case 41:
@@ -2121,12 +2161,12 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                case 45:
                case 46:
                case 47:
-                       terminal->pvt->screen->defaults.attr.back = VTE_LEGACY_COLORS_OFFSET + param - 40;
+                        terminal->pvt->defaults.attr.back = VTE_LEGACY_COLORS_OFFSET + param - 40;
                        break;
             /* case 48: was handled above at 38 to avoid code duplication */
                case 49:
                        /* default background */
-                       terminal->pvt->screen->defaults.attr.back = VTE_DEFAULT_BG;
+                        terminal->pvt->defaults.attr.back = VTE_DEFAULT_BG;
                        break;
                case 90:
                case 91:
@@ -2136,7 +2176,7 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                case 95:
                case 96:
                case 97:
-                       terminal->pvt->screen->defaults.attr.fore = VTE_LEGACY_COLORS_OFFSET + param - 90 + 
VTE_COLOR_BRIGHT_OFFSET;
+                        terminal->pvt->defaults.attr.fore = VTE_LEGACY_COLORS_OFFSET + param - 90 + 
VTE_COLOR_BRIGHT_OFFSET;
                        break;
                case 100:
                case 101:
@@ -2146,7 +2186,7 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                case 105:
                case 106:
                case 107:
-                       terminal->pvt->screen->defaults.attr.back = VTE_LEGACY_COLORS_OFFSET + param - 100 + 
VTE_COLOR_BRIGHT_OFFSET;
+                        terminal->pvt->defaults.attr.back = VTE_LEGACY_COLORS_OFFSET + param - 100 + 
VTE_COLOR_BRIGHT_OFFSET;
                        break;
                }
        }
@@ -2155,14 +2195,14 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
                _vte_terminal_set_default_attributes(terminal);
        }
        /* Save the new colors. */
-       terminal->pvt->screen->color_defaults.attr.fore =
-               terminal->pvt->screen->defaults.attr.fore;
-       terminal->pvt->screen->color_defaults.attr.back =
-               terminal->pvt->screen->defaults.attr.back;
-       terminal->pvt->screen->fill_defaults.attr.fore =
-               terminal->pvt->screen->defaults.attr.fore;
-       terminal->pvt->screen->fill_defaults.attr.back =
-               terminal->pvt->screen->defaults.attr.back;
+        terminal->pvt->color_defaults.attr.fore =
+                terminal->pvt->defaults.attr.fore;
+        terminal->pvt->color_defaults.attr.back =
+                terminal->pvt->defaults.attr.back;
+        terminal->pvt->fill_defaults.attr.fore =
+                terminal->pvt->defaults.attr.fore;
+        terminal->pvt->fill_defaults.attr.back =
+                terminal->pvt->defaults.attr.back;
 }
 
 /* Move the cursor to the given column in the top row, 1-based. */
@@ -2552,9 +2592,9 @@ vte_sequence_handler_insert_lines (VteTerminal *terminal, GValueArray *params)
                }
        }
        /* Find the region we're messing with. */
-       row = screen->cursor_current.row;
-       if (screen->scrolling_restricted) {
-               end = screen->insert_delta + screen->scrolling_region.end;
+        row = terminal->pvt->cursor.row;
+        if (terminal->pvt->scrolling_restricted) {
+                end = screen->insert_delta + terminal->pvt->scrolling_region.end;
        } else {
                end = screen->insert_delta + terminal->pvt->row_count - 1;
        }
@@ -2571,7 +2611,7 @@ vte_sequence_handler_insert_lines (VteTerminal *terminal, GValueArray *params)
                _vte_terminal_ring_remove (terminal, end);
                _vte_terminal_ring_insert (terminal, row, TRUE);
        }
-        terminal->pvt->screen->cursor_current.col = 0;
+        terminal->pvt->cursor.col = 0;
        /* Update the display. */
        _vte_terminal_scroll_region(terminal, row, end - row + 1, param);
        /* Adjust the scrollbars if necessary. */
@@ -2599,9 +2639,9 @@ vte_sequence_handler_delete_lines (VteTerminal *terminal, GValueArray *params)
                }
        }
        /* Find the region we're messing with. */
-       row = screen->cursor_current.row;
-       if (screen->scrolling_restricted) {
-               end = screen->insert_delta + screen->scrolling_region.end;
+        row = terminal->pvt->cursor.row;
+        if (terminal->pvt->scrolling_restricted) {
+                end = screen->insert_delta + terminal->pvt->scrolling_region.end;
        } else {
                end = screen->insert_delta + terminal->pvt->row_count - 1;
        }
@@ -2619,7 +2659,7 @@ vte_sequence_handler_delete_lines (VteTerminal *terminal, GValueArray *params)
                _vte_terminal_ring_remove (terminal, row);
                _vte_terminal_ring_insert (terminal, end, TRUE);
        }
-        terminal->pvt->screen->cursor_current.col = 0;
+        terminal->pvt->cursor.col = 0;
        /* Update the display. */
        _vte_terminal_scroll_region(terminal, row, end - row + 1, -param);
        /* Adjust the scrollbars if necessary. */
@@ -2651,20 +2691,20 @@ vte_sequence_handler_device_status_report (VteTerminal *terminal, GValueArray *p
                                break;
                        case 6:
                                /* Send the cursor position. */
-                                if (screen->origin_mode &&
-                                    screen->scrolling_restricted) {
-                                        origin = screen->scrolling_region.start;
-                                        rowmax = screen->scrolling_region.end;
+                                if (terminal->pvt->origin_mode &&
+                                    terminal->pvt->scrolling_restricted) {
+                                        origin = terminal->pvt->scrolling_region.start;
+                                        rowmax = terminal->pvt->scrolling_region.end;
                                 } else {
                                         origin = 0;
                                         rowmax = terminal->pvt->row_count - 1;
                                 }
-                                rowval = screen->cursor_current.row - screen->insert_delta - origin;
+                                rowval = terminal->pvt->cursor.row - screen->insert_delta - origin;
                                 rowval = CLAMP(rowval, 0, rowmax);
                                g_snprintf(buf, sizeof(buf),
                                           _VTE_CAP_CSI "%ld;%ldR",
                                            rowval + 1,
-                                           CLAMP(screen->cursor_current.col + 1,
+                                           CLAMP(terminal->pvt->cursor.col + 1,
                                                  1, terminal->pvt->column_count));
                                vte_terminal_feed_child(terminal, buf, -1);
                                break;
@@ -2693,20 +2733,20 @@ vte_sequence_handler_dec_device_status_report (VteTerminal *terminal, GValueArra
                        switch (param) {
                        case 6:
                                /* Send the cursor position. */
-                                if (screen->origin_mode &&
-                                    screen->scrolling_restricted) {
-                                        origin = screen->scrolling_region.start;
-                                        rowmax = screen->scrolling_region.end;
+                                if (terminal->pvt->origin_mode &&
+                                    terminal->pvt->scrolling_restricted) {
+                                        origin = terminal->pvt->scrolling_region.start;
+                                        rowmax = terminal->pvt->scrolling_region.end;
                                 } else {
                                         origin = 0;
                                         rowmax = terminal->pvt->row_count - 1;
                                 }
-                                rowval = screen->cursor_current.row - screen->insert_delta - origin;
+                                rowval = terminal->pvt->cursor.row - screen->insert_delta - origin;
                                 rowval = CLAMP(rowval, 0, rowmax);
                                g_snprintf(buf, sizeof(buf),
                                           _VTE_CAP_CSI "?%ld;%ldR",
                                            rowval + 1,
-                                           CLAMP(screen->cursor_current.col + 1,
+                                           CLAMP(terminal->pvt->cursor.col + 1,
                                                  1, terminal->pvt->column_count));
                                vte_terminal_feed_child(terminal, buf, -1);
                                break;



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