[vte] emulation: Track the cursor separately for the two screens



commit e9791aba2ff1839ce7e383b29da2e0d0eadd566e
Author: Egmont Koblinger <egmont gmail com>
Date:   Thu Jan 28 14:06:11 2016 +0100

    emulation: Track the cursor separately for the two screens
    
    This is required to correctly resize the normal screen's contents
    while the alternate screen is active, fixing a bug introduced by
    commit 5a434e6c4457bdfe182a13213396e7a66a08f767.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=761097

 src/vte.cc         |  154 ++++++++++++++++++++++++++--------------------------
 src/vtegtk.cc      |    4 +-
 src/vteinternal.hh |    5 +-
 src/vteseq.cc      |  124 +++++++++++++++++++++---------------------
 4 files changed, 142 insertions(+), 145 deletions(-)
---
diff --git a/src/vte.cc b/src/vte.cc
index d603922..fc560c3 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -663,8 +663,8 @@ VteTerminalPrivate::invalidate_cursor_once(bool periodic)
 
        if (m_cursor_visible) {
                auto preedit_width = get_preedit_width(false);
-                auto row = m_cursor.row;
-                auto column = m_cursor.col;
+                auto row = m_screen->cursor.row;
+                auto column = m_screen->cursor.col;
                long columns = 1;
                column = find_start_column (m_terminal, column, row);
 
@@ -2200,8 +2200,8 @@ VteTerminalPrivate::adjust_adjustments()
         * area.  Leave the scrolling delta alone because it will be updated
         * when the adjustment changes. */
        screen->insert_delta = MAX(m_screen->insert_delta, delta);
-        m_cursor.row = MAX(m_cursor.row,
-                           m_screen->insert_delta);
+        m_screen->cursor.row = MAX(m_screen->cursor.row,
+                                   m_screen->insert_delta);
 
        if (m_screen->scroll_delta > m_screen->insert_delta) {
                queue_adjustment_value_changed(m_screen->insert_delta);
@@ -2420,13 +2420,13 @@ VteTerminalPrivate::ensure_row()
 
        /* Figure out how many rows we need to add. */
         //FIXMEchpe use long, not int
-       int delta = m_cursor.row - _vte_ring_next(m_screen->row_data) + 1;
+       int delta = m_screen->cursor.row - _vte_ring_next(m_screen->row_data) + 1;
        if (delta > 0) {
                row = insert_rows(delta);
                adjust_adjustments();
        } else {
                /* Find the row the cursor is in. */
-               row = _vte_ring_index_writable(m_screen->row_data, m_cursor.row);
+               row = _vte_ring_index_writable(m_screen->row_data, m_screen->cursor.row);
        }
        g_assert(row != NULL);
 
@@ -2437,7 +2437,7 @@ VteRowData *
 VteTerminalPrivate::ensure_cursor()
 {
        VteRowData *row = ensure_row();
-        _vte_row_data_fill(row, &basic_cell.cell, m_cursor.col);
+        _vte_row_data_fill(row, &basic_cell.cell, m_screen->cursor.col);
 
        return row;
 }
@@ -2450,7 +2450,7 @@ VteTerminalPrivate::update_insert_delta()
        /* The total number of lines.  Add one to the cursor offset
         * because it's zero-based. */
        auto rows = _vte_ring_next(m_screen->row_data);
-        auto delta = m_cursor.row - rows + 1;
+        auto delta = m_screen->cursor.row - rows + 1;
        if (G_UNLIKELY (delta > 0)) {
                insert_rows(delta);
                rows = _vte_ring_next(m_screen->row_data);
@@ -2462,7 +2462,7 @@ VteTerminalPrivate::update_insert_delta()
        delta = m_screen->insert_delta;
        delta = MIN(delta, rows - m_row_count);
        delta = MAX(delta,
-                    m_cursor.row - (m_row_count - 1));
+                    m_screen->cursor.row - (m_row_count - 1));
        delta = MAX(delta, _vte_ring_delta(m_screen->row_data));
 
        /* Adjust the insert delta and scroll if needed. */
@@ -3010,7 +3010,7 @@ VteTerminalPrivate::cleanup_fragments(long start,
                         cell_end->attr.columns = 1;
                         invalidate_cells(
                                               end, 1,
-                                              m_cursor.row, 1);
+                                              m_screen->cursor.row, 1);
                 }
         }
 
@@ -3036,7 +3036,7 @@ VteTerminalPrivate::cleanup_fragments(long start,
                                         g_assert(start - col == 1);
                                         invalidate_cells(
                                                               col, 1,
-                                                              m_cursor.row, 1);
+                                                              m_screen->cursor.row, 1);
                                 }
                                 keep_going = FALSE;
                         }
@@ -3060,19 +3060,19 @@ VteTerminalPrivate::cursor_down()
                start = m_screen->insert_delta;
                end = start + m_row_count - 1;
        }
-        if (m_cursor.row == end) {
+        if (m_screen->cursor.row == end) {
                 if (m_scrolling_restricted) {
                        if (start == m_screen->insert_delta) {
                                /* Scroll this line into the scrollback
                                 * buffer by inserting a line at the next
                                 * line and scrolling the area up. */
                                m_screen->insert_delta++;
-                                m_cursor.row++;
+                                m_screen->cursor.row++;
                                /* update start and end, as they are relative
                                 * to insert_delta. */
                                start++;
                                end++;
-                                _vte_terminal_ring_insert(m_terminal, m_cursor.row, FALSE);
+                                _vte_terminal_ring_insert(m_terminal, m_screen->cursor.row, FALSE);
                                /* Force the areas below the region to be
                                 * redrawn -- they've moved. */
                                scroll_region(start,
@@ -3094,7 +3094,7 @@ VteTerminalPrivate::cursor_down()
                        }
                } else {
                        /* Scroll up with history. */
-                        m_cursor.row++;
+                        m_screen->cursor.row++;
                        update_insert_delta();
                }
 
@@ -3107,7 +3107,7 @@ VteTerminalPrivate::cursor_down()
 #endif
        } else {
                /* Otherwise, just move the cursor down. */
-                m_cursor.row++;
+                m_screen->cursor.row++;
        }
 }
 
@@ -3129,9 +3129,9 @@ VteTerminalPrivate::drop_scrollback()
 void
 VteTerminalPrivate::restore_cursor(VteScreen *screen__)
 {
-        m_cursor.col = screen__->saved.cursor.col;
-        m_cursor.row = screen__->insert_delta + CLAMP(screen__->saved.cursor.row,
-                                                      0, m_row_count - 1);
+        screen__->cursor.col = screen__->saved.cursor.col;
+        screen__->cursor.row = screen__->insert_delta + CLAMP(screen__->saved.cursor.row,
+                                                              0, m_row_count - 1);
 
         m_reverse_mode = screen__->saved.reverse_mode;
         m_origin_mode = screen__->saved.origin_mode;
@@ -3150,8 +3150,8 @@ VteTerminalPrivate::restore_cursor(VteScreen *screen__)
 void
 VteTerminalPrivate::save_cursor(VteScreen *screen__)
 {
-        screen__->saved.cursor.col = m_cursor.col;
-        screen__->saved.cursor.row = m_cursor.row - screen__->insert_delta;
+        screen__->saved.cursor.col = screen__->cursor.col;
+        screen__->saved.cursor.row = screen__->cursor.row - screen__->insert_delta;
 
         screen__->saved.reverse_mode = m_reverse_mode;
         screen__->saved.origin_mode = m_origin_mode;
@@ -3230,21 +3230,21 @@ VteTerminalPrivate::insert_char(gunichar c,
         columns = _vte_unichar_width(c, m_utf8_ambiguous_width);
 
        /* If we're autowrapping here, do it. */
-        col = m_cursor.col;
+        col = m_screen->cursor.col;
        if (G_UNLIKELY (columns && col + columns > m_column_count)) {
                if (m_autowrap) {
                        _vte_debug_print(VTE_DEBUG_ADJ,
                                        "Autowrapping before character\n");
                        /* Wrap. */
                        /* XXX clear to the end of line */
-                        col = m_cursor.col = 0;
+                        col = m_screen->cursor.col = 0;
                        /* Mark this line as soft-wrapped. */
                        row = ensure_row();
                        row->attr.soft_wrapped = 1;
                        cursor_down();
                } else {
                        /* Don't wrap, stay at the rightmost column. */
-                        col = m_cursor.col =
+                        col = m_screen->cursor.col =
                                m_column_count - columns;
                }
                line_wrapped = true;
@@ -3255,7 +3255,7 @@ VteTerminalPrivate::insert_char(gunichar c,
                        (long)c, c < 256 ? c : ' ',
                          (int)m_color_defaults.attr.fore,
                          (int)m_color_defaults.attr.back,
-                        col, columns, (long)m_cursor.row,
+                        col, columns, (long)m_screen->cursor.row,
                        (long)m_screen->insert_delta);
 
        if (G_UNLIKELY (columns == 0)) {
@@ -3267,7 +3267,7 @@ VteTerminalPrivate::insert_char(gunichar c,
 
                _vte_debug_print(VTE_DEBUG_PARSE, "combining U+%04X", c);
 
-                row_num = m_cursor.row;
+                row_num = m_screen->cursor.row;
                row = NULL;
                if (G_UNLIKELY (col == 0)) {
                        /* We are at first column.  See if the previous line softwrapped.
@@ -3367,10 +3367,10 @@ VteTerminalPrivate::insert_char(gunichar c,
                invalidate_cells(
                                col - columns,
                                insert ? m_column_count : columns,
-                                m_cursor.row, 1);
+                                m_screen->cursor.row, 1);
        }
 
-        m_cursor.col = col;
+        m_screen->cursor.col = col;
 
 done:
        /* We added text, so make a note of it. */
@@ -3721,12 +3721,12 @@ VteTerminalPrivate::process_incoming()
         auto bottom_row = last_displayed_row();
 
        /* Save the current cursor position. */
-        saved_cursor = m_cursor;
+        saved_cursor = m_screen->cursor;
        saved_cursor_visible = m_cursor_visible;
 
         in_scroll_region = m_scrolling_restricted
-            && (m_cursor.row >= (m_screen->insert_delta + m_scrolling_region.start))
-            && (m_cursor.row <= (m_screen->insert_delta + m_scrolling_region.end));
+            && (m_screen->cursor.row >= (m_screen->insert_delta + m_scrolling_region.start))
+            && (m_screen->cursor.row <= (m_screen->insert_delta + m_scrolling_region.end));
 
        /* We should only be called when there's data to process. */
        g_assert(m_incoming ||
@@ -3835,8 +3835,8 @@ skip_chunk:
                        modified = TRUE;
 
                         new_in_scroll_region = m_scrolling_restricted
-                            && (m_cursor.row >= (screen->insert_delta + m_scrolling_region.start))
-                            && (m_cursor.row <= (screen->insert_delta + m_scrolling_region.end));
+                            && (m_screen->cursor.row >= (screen->insert_delta + m_scrolling_region.start))
+                            && (m_screen->cursor.row <= (screen->insert_delta + m_scrolling_region.end));
 
                         /* delta may have changed from sequence. */
                         top_row = first_displayed_row();
@@ -3847,10 +3847,10 @@ skip_chunk:
                          */
                        if (invalidated_text &&
                                        ((new_in_scroll_region && !in_scroll_region) ||
-                                         (m_cursor.col > bbox_bottomright.x + VTE_CELL_BBOX_SLACK ||
-                                          m_cursor.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK     ||
-                                          m_cursor.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK ||
-                                          m_cursor.row < bbox_topleft.y - VTE_CELL_BBOX_SLACK))) {
+                                         (m_screen->cursor.col > bbox_bottomright.x + VTE_CELL_BBOX_SLACK ||
+                                          m_screen->cursor.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK     ||
+                                          m_screen->cursor.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK ||
+                                          m_screen->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, top_row);
@@ -3930,19 +3930,19 @@ skip_chunk:
                        }
 
                        bbox_topleft.x = MIN(bbox_topleft.x,
-                                        m_cursor.col);
+                                             m_screen->cursor.col);
                        bbox_topleft.y = MIN(bbox_topleft.y,
-                                        m_cursor.row);
+                                             m_screen->cursor.row);
 
                        /* Insert the character. */
                         // FIXMEchpe should not use UNLIKELY here
                        if (G_UNLIKELY(insert_char(c, false, false))) {
                                /* line wrapped, correct bbox */
                                if (invalidated_text &&
-                                                (m_cursor.col > bbox_bottomright.x + VTE_CELL_BBOX_SLACK     
  ||
-                                                 m_cursor.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK   ||
-                                                 m_cursor.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK     
  ||
-                                                 m_cursor.row < bbox_topleft.y - VTE_CELL_BBOX_SLACK)) {
+                                                (m_screen->cursor.col > bbox_bottomright.x + 
VTE_CELL_BBOX_SLACK       ||
+                                                 m_screen->cursor.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK 
  ||
+                                                 m_screen->cursor.row > bbox_bottomright.y + 
VTE_CELL_BBOX_SLACK       ||
+                                                 m_screen->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, top_row);
@@ -3963,15 +3963,15 @@ skip_chunk:
                                }
                                bbox_topleft.x = MIN(bbox_topleft.x, 0);
                                bbox_topleft.y = MIN(bbox_topleft.y,
-                                                     m_cursor.row);
+                                                     m_screen->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,
-                                                 m_cursor.col);
+                                                 m_screen->cursor.col);
                         /* cursor.row + 1 (defer until inv.) */
                        bbox_bottomright.y = MAX(bbox_bottomright.y,
-                                                 m_cursor.row);
+                                                 m_screen->cursor.row);
                        invalidated_text = TRUE;
 
                        /* We *don't* emit flush pending signals here. */
@@ -4005,7 +4005,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(m_cursor.row >= m_screen->insert_delta);
+                g_assert(m_screen->cursor.row >= m_screen->insert_delta);
 #endif
 
 next_match:
@@ -4072,8 +4072,8 @@ next_match:
        }
 
 
-        if ((saved_cursor.col != m_cursor.col) ||
-            (saved_cursor.row != m_cursor.row)) {
+        if ((saved_cursor.col != m_screen->cursor.col) ||
+            (saved_cursor.row != m_screen->cursor.row)) {
                /* invalidate the old and new cursor positions */
                if (cursor_visible)
                        invalidate_cell(saved_cursor.col, saved_cursor.row);
@@ -4089,10 +4089,9 @@ next_match:
        /* Tell the input method where the cursor is. */
        if (widget_realized()) {
                GdkRectangle rect;
-                rect.x = m_cursor.col *
-                        m_char_width + m_padding.left;
+                rect.x = m_screen->cursor.col * m_char_width + m_padding.left;
                rect.width = m_char_width; // FIXMEchpe: if columns > 1 ?
-                rect.y = row_to_pixel(m_cursor.row) + m_padding.top;
+                rect.y = row_to_pixel(m_screen->cursor.row) + m_padding.top;
                rect.height = m_char_height;
                gtk_im_context_set_cursor_location(m_im_context,
                                                   &rect);
@@ -4856,7 +4855,7 @@ VteTerminalPrivate::widget_key_press(GdkEventKey *event)
                /* If we're in margin bell mode and on the border of the
                 * margin, bell. */
                if (m_margin_bell) {
-                        if ((m_cursor.col +
+                        if ((m_screen->cursor.col +
                             (glong) m_bell_margin) == m_column_count) {
                                beep();
                        }
@@ -7771,14 +7770,14 @@ VteTerminalPrivate::screen_set_size(VteScreen *screen_,
                        "     cursor_saved (relative to insert_delta)  row=%ld  col=%ld\n",
                        screen_ == &m_normal_screen ? "normal" : "alternate",
                        screen_->insert_delta, screen_->scroll_delta,
-                        m_cursor.row, m_cursor.col,
+                        screen_->cursor.row, screen_->cursor.col,
                         screen_->saved.cursor.row, screen_->saved.cursor.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 = m_cursor.row + 1;
+        below_current_paragraph.row = screen_->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++;
@@ -7788,15 +7787,12 @@ VteTerminalPrivate::screen_set_size(VteScreen *screen_,
         markers[0] = &cursor_saved_absolute;
         markers[1] = &below_viewport;
         markers[2] = &below_current_paragraph;
-        if (screen_ == m_screen) {
-                /* Tracking the current cursor only makes sense on the active screen_. */
-                markers[3] = &m_cursor;
-                if (m_has_selection) {
-                        /* selection_end is inclusive, make it non-inclusive, see bug 722635. */
-                        m_selection_end.col++;
-                        markers[4] = &m_selection_start;
-                        markers[5] = &m_selection_end;
-                }
+        markers[3] = &screen_->cursor;
+        if (m_has_selection) {
+                /* selection_end is inclusive, make it non-inclusive, see bug 722635. */
+                m_selection_end.col++;
+                markers[4] = &m_selection_start;
+                markers[5] = &m_selection_end;
        }
 
        old_top_lines = below_current_paragraph.row - screen_->insert_delta;
@@ -7824,7 +7820,7 @@ VteTerminalPrivate::screen_set_size(VteScreen *screen_,
                }
        }
 
-       if (screen_ == m_screen && m_has_selection) {
+       if (m_has_selection) {
                /* Make selection_end inclusive again, see above. */
                m_selection_end.col--;
        }
@@ -7875,7 +7871,7 @@ VteTerminalPrivate::screen_set_size(VteScreen *screen_,
                         "     cursor (absolute)  row=%ld  col=%ld\n"
                        "     cursor_saved (relative to insert_delta)  row=%ld  col=%ld\n\n",
                        screen_->insert_delta, new_scroll_delta,
-                        m_cursor.row, m_cursor.col,
+                        screen_->cursor.row, screen_->cursor.col,
                         screen_->saved.cursor.row, screen_->saved.cursor.col);
 
        if (screen_ == m_screen)
@@ -7928,10 +7924,10 @@ VteTerminalPrivate::set_size(long columns,
                 vte_terminal_set_scrollback_lines(m_terminal,
                                                   m_scrollback_lines);
                 /* Ensure the cursor is valid */
-                m_cursor.row = CLAMP (m_cursor.row,
-                                                    _vte_ring_delta (m_screen->row_data),
-                                                    MAX (_vte_ring_delta (m_screen->row_data),
-                                                         _vte_ring_next (m_screen->row_data) - 1));
+                m_screen->cursor.row = CLAMP (m_screen->cursor.row,
+                                              _vte_ring_delta (m_screen->row_data),
+                                              MAX (_vte_ring_delta (m_screen->row_data),
+                                                   _vte_ring_next (m_screen->row_data) - 1));
 
                adjust_adjustments_full();
                gtk_widget_queue_resize_no_redraw(m_widget);
@@ -9557,8 +9553,8 @@ VteTerminalPrivate::paint_cursor()
         if (m_im_preedit_active)
                 return;
 
-        col = m_cursor.col;
-        drow = m_cursor.row;
+        col = m_screen->cursor.col;
+        drow = m_screen->cursor.row;
        width = m_char_width;
        height = m_char_height;
 
@@ -9690,7 +9686,7 @@ VteTerminalPrivate::paint_im_preedit_string()
 
        /* 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 = m_cursor.col;
+        col = m_screen->cursor.col;
        if (col + columns > m_column_count) {
                col = MAX(0, m_column_count - columns);
        }
@@ -9707,13 +9703,13 @@ VteTerminalPrivate::paint_im_preedit_string()
                         items[i].columns = _vte_unichar_width(items[i].c,
                                                               m_utf8_ambiguous_width);
                        items[i].x = (col + columns) * width;
-                       items[i].y = row_to_pixel(m_cursor.row);
+                       items[i].y = row_to_pixel(m_screen->cursor.row);
                        columns += items[i].columns;
                        preedit = g_utf8_next_char(preedit);
                }
                _vte_draw_clear(m_draw,
                                col * width,
-                               row_to_pixel(m_cursor.row),
+                               row_to_pixel(m_screen->cursor.row),
                                width * columns,
                                height,
                                 get_color(VTE_DEFAULT_BG), m_background_alpha);
@@ -10183,7 +10179,7 @@ VteTerminalPrivate::set_scrollback_lines(long lines)
         /* The main screen gets the full scrollback buffer. */
         scrn = &m_normal_screen;
         lines = MAX (lines, m_row_count);
-        next = MAX (m_cursor.row + 1,
+        next = MAX (m_screen->cursor.row + 1,
                     _vte_ring_next (scrn->row_data));
         _vte_ring_resize (scrn->row_data, lines);
         low = _vte_ring_delta (scrn->row_data);
@@ -10302,10 +10298,12 @@ VteTerminalPrivate::reset(bool clear_tabstops,
                 m_screen = &m_normal_screen;
                 m_normal_screen.scroll_delta = m_normal_screen.insert_delta =
                         _vte_ring_reset(m_normal_screen.row_data);
+                m_normal_screen.cursor.row = m_normal_screen.insert_delta;
+                m_normal_screen.cursor.col = 0;
                 m_alternate_screen.scroll_delta = m_alternate_screen.insert_delta =
                         _vte_ring_reset(m_alternate_screen.row_data);
-                m_cursor.row = m_screen->insert_delta;
-                m_cursor.col = 0;
+                m_alternate_screen.cursor.row = m_alternate_screen.insert_delta;
+                m_alternate_screen.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. */
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 465407d..0c1a7b5 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -2152,10 +2152,10 @@ vte_terminal_get_cursor_position(VteTerminal *terminal,
 
         auto impl = IMPL(terminal);
        if (column) {
-                *column = impl->m_cursor.col;
+                *column = impl->m_screen->cursor.col;
        }
        if (row) {
-                *row = impl->m_cursor.row;
+                *row = impl->m_screen->cursor.row;
        }
 }
 
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 812ff0b..c69715a 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -132,12 +132,13 @@ struct _vte_incoming_chunk{
 typedef struct _VteScreen VteScreen;
 struct _VteScreen {
         VteRing row_data[1];   /* buffer contents */
+        VteVisualPosition cursor;  /* absolute value, from the beginning of the terminal history */
         double scroll_delta;   /* scroll offset */
         long insert_delta;     /* insertion offset */
 
         /* Stuff saved along with the cursor */
         struct {
-                VteVisualPosition cursor;
+                VteVisualPosition cursor;  /* onscreen coordinate, that is, relative to insert_delta */
                 gboolean reverse_mode;
                 gboolean origin_mode;
                 gboolean sendrecv_mode;
@@ -331,7 +332,6 @@ public:
 #define m_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 */
@@ -1187,7 +1187,6 @@ public:
 #define m_draw draw
 #define m_cursor_blinks cursor_blinks
 #define m_cursor_visible cursor_visible
-#define m_cursor cursor
 #define m_cursor_blink_state cursor_blink_state
 #define m_cursor_blink_time cursor_blink_time
 #define m_cursor_blink_cycle cursor_blink_cycle
diff --git a/src/vteseq.cc b/src/vteseq.cc
index d00fafb..ed61641 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -220,8 +220,8 @@ VteTerminalPrivate::emit_resize_window(guint columns,
 void
 VteTerminalPrivate::ensure_cursor_is_onscreen()
 {
-        if (G_UNLIKELY (m_cursor.col >= m_column_count))
-                m_cursor.col = m_column_count - 1;
+        if (G_UNLIKELY (m_screen->cursor.col >= m_column_count))
+                m_screen->cursor.col = m_column_count - 1;
 }
 
 void
@@ -234,7 +234,7 @@ VteTerminalPrivate::seq_home_cursor()
 void
 VteTerminalPrivate::seq_clear_screen()
 {
-        auto row = m_cursor.row - screen->insert_delta;
+        auto row = m_screen->cursor.row - screen->insert_delta;
         auto initial = _vte_ring_next(m_screen->row_data);
        /* Add a new screen's worth of rows. */
         for (auto i = 0; i < m_row_count; i++)
@@ -242,7 +242,7 @@ VteTerminalPrivate::seq_clear_screen()
        /* Move the cursor and insertion delta to the first line in the
         * newly-cleared area and scroll if need be. */
         m_screen->insert_delta = initial;
-        m_cursor.row = row + m_screen->insert_delta;
+        m_screen->cursor.row = row + m_screen->insert_delta;
         adjust_adjustments();
        /* Redraw everything. */
         invalidate_all();
@@ -258,9 +258,9 @@ VteTerminalPrivate::seq_clear_current_line()
 
        /* If the cursor is actually on the screen, clear data in the row
         * which corresponds to the cursor. */
-        if (_vte_ring_next(m_screen->row_data) > m_cursor.row) {
+        if (_vte_ring_next(m_screen->row_data) > m_screen->cursor.row) {
                /* Get the data for the row which the cursor points to. */
-                rowdata = _vte_ring_index_writable(m_screen->row_data, m_cursor.row);
+                rowdata = _vte_ring_index_writable(m_screen->row_data, m_screen->cursor.row);
                g_assert(rowdata != NULL);
                /* Remove it. */
                _vte_row_data_shrink (rowdata, 0);
@@ -269,7 +269,7 @@ VteTerminalPrivate::seq_clear_current_line()
                rowdata->attr.soft_wrapped = 0;
                /* Repaint this row. */
                invalidate_cells(0, m_column_count,
-                                 m_cursor.row, 1);
+                                 m_screen->cursor.row, 1);
        }
 
        /* We've modified the display.  Make a note of it. */
@@ -282,7 +282,7 @@ VteTerminalPrivate::seq_clear_above_current()
 {
        /* If the cursor is actually on the screen, clear data in the row
         * which corresponds to the cursor. */
-        for (auto i = m_screen->insert_delta; i < m_cursor.row; i++) {
+        for (auto i = m_screen->insert_delta; i < m_screen->cursor.row; i++) {
                 if (_vte_ring_next(m_screen->row_data) > i) {
                        /* Get the data for the row we're erasing. */
                         auto rowdata = _vte_ring_index_writable(m_screen->row_data, i);
@@ -385,9 +385,9 @@ VteTerminalPrivate::seq_switch_screen(VteScreen *new_screen)
         /* if (new_screen == m_screen) return; ? */
 
         /* cursor.row includes insert_delta, adjust accordingly */
-        m_cursor.row -= m_screen->insert_delta;
+        auto cr = m_screen->cursor.row - m_screen->insert_delta;
         m_screen = new_screen;
-        m_cursor.row += m_screen->insert_delta;
+        m_screen->cursor.row = cr + m_screen->insert_delta;
 
         /* Make sure the ring is large enough */
         ensure_row();
@@ -557,7 +557,7 @@ vte_sequence_handler_multiple_r(VteTerminalPrivate *that,
                                 VteTerminalSequenceHandler handler)
 {
         vte_sequence_handler_multiple_limited(that, params, handler,
-                                              that->column_count - that->cursor.col);
+                                              that->column_count - that->m_screen->cursor.col);
 }
 
 static void
@@ -1027,7 +1027,7 @@ void
 VteTerminalPrivate::seq_cursor_back_tab()
 {
        /* Calculate which column is the previous tab stop. */
-        auto newcol = m_cursor.col;
+        auto newcol = m_screen->cursor.col;
 
        if (m_tabstops) {
                /* Find the next tabstop. */
@@ -1054,12 +1054,12 @@ VteTerminalPrivate::seq_cb()
        /* Get the data for the row which the cursor points to. */
        auto rowdata = ensure_row();
         /* Clean up Tab/CJK fragments. */
-        cleanup_fragments(0, m_cursor.col + 1);
+        cleanup_fragments(0, m_screen->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. */
         vte::grid::column_t i;
-        for (i = 0; i <= m_cursor.col; i++) {
+        for (i = 0; i <= m_screen->cursor.col; i++) {
                 if (i < (glong) _vte_row_data_length (rowdata)) {
                        /* Muck with the cell in this location. */
                         auto pcell = _vte_row_data_get_writable(rowdata, i);
@@ -1070,8 +1070,8 @@ VteTerminalPrivate::seq_cb()
                }
        }
        /* Repaint this row. */
-        invalidate_cells(0, m_cursor.col+1,
-                         m_cursor.row, 1);
+        invalidate_cells(0, m_screen->cursor.col+1,
+                         m_screen->cursor.row, 1);
 
        /* We've modified the display.  Make a note of it. */
         m_text_deleted_flag = TRUE;
@@ -1086,19 +1086,19 @@ VteTerminalPrivate::seq_cd()
        /* 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. */
         VteRowData *rowdata;
-        auto i = m_cursor.row;
+        auto i = m_screen->cursor.row;
        if (i < _vte_ring_next(m_screen->row_data)) {
                /* Get the data for the row we're clipping. */
                 rowdata = _vte_ring_index_writable(m_screen->row_data, i);
                 /* Clean up Tab/CJK fragments. */
-                if ((glong) _vte_row_data_length(rowdata) > m_cursor.col)
-                        cleanup_fragments(m_cursor.col, _vte_row_data_length(rowdata));
+                if ((glong) _vte_row_data_length(rowdata) > m_screen->cursor.col)
+                        cleanup_fragments(m_screen->cursor.col, _vte_row_data_length(rowdata));
                /* Clear everything to the right of the cursor. */
                if (rowdata)
-                        _vte_row_data_shrink(rowdata, m_cursor.col);
+                        _vte_row_data_shrink(rowdata, m_screen->cursor.col);
        }
        /* Now for the rest of the lines. */
-        for (i = m_cursor.row + 1;
+        for (i = m_screen->cursor.row + 1;
             i < _vte_ring_next(m_screen->row_data);
             i++) {
                /* Get the data for the row we're removing. */
@@ -1108,7 +1108,7 @@ VteTerminalPrivate::seq_cd()
                        _vte_row_data_shrink (rowdata, 0);
        }
        /* Now fill the cleared areas. */
-        for (i = m_cursor.row;
+        for (i = m_screen->cursor.row;
             i < m_screen->insert_delta + m_row_count;
             i++) {
                /* Retrieve the row's data, creating it if necessary. */
@@ -1147,12 +1147,12 @@ VteTerminalPrivate::seq_ce()
        /* Get the data for the row which the cursor points to. */
         auto rowdata = ensure_row();
        g_assert(rowdata != NULL);
-        if ((glong) _vte_row_data_length(rowdata) > m_cursor.col) {
+        if ((glong) _vte_row_data_length(rowdata) > m_screen->cursor.col) {
                 /* Clean up Tab/CJK fragments. */
-                cleanup_fragments(m_cursor.col, _vte_row_data_length(rowdata));
+                cleanup_fragments(m_screen->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, m_cursor.col);
+                _vte_row_data_shrink(rowdata, m_screen->cursor.col);
                /* We've modified the display.  Make a note of it. */
                m_text_deleted_flag = TRUE;
        }
@@ -1162,8 +1162,8 @@ VteTerminalPrivate::seq_ce()
        }
        rowdata->attr.soft_wrapped = 0;
        /* Repaint this row. */
-       invalidate_cells(m_cursor.col, m_column_count - m_cursor.col,
-                         m_cursor.row, 1);
+       invalidate_cells(m_screen->cursor.col, m_column_count - m_screen->cursor.col,
+                         m_screen->cursor.row, 1);
 }
 
 /* Move the cursor to the given column (horizontal position), 1-based. */
@@ -1193,7 +1193,7 @@ vte_sequence_handler_cursor_character_absolute (VteTerminalPrivate *that, GValue
 void
 VteTerminalPrivate::set_cursor_column(vte::grid::column_t col)
 {
-        m_cursor.col = CLAMP(col, 0, m_column_count - 1);
+        m_screen->cursor.col = CLAMP(col, 0, m_column_count - 1);
 }
 
 /*
@@ -1218,7 +1218,7 @@ VteTerminalPrivate::set_cursor_row(vte::grid::row_t row)
         row += start_row;
         row = CLAMP(row, start_row, end_row);
 
-        m_cursor.row = row + m_screen->insert_delta;
+        m_screen->cursor.row = row + m_screen->insert_delta;
 }
 
 /*
@@ -1230,7 +1230,7 @@ VteTerminalPrivate::set_cursor_row(vte::grid::row_t row)
 vte::grid::row_t
 VteTerminalPrivate::get_cursor_row() const
 {
-        auto row = m_cursor.row - m_screen->insert_delta;
+        auto row = m_screen->cursor.row - m_screen->insert_delta;
         /* Note that we do NOT check m_origin_mode here! */
         if (m_scrolling_restricted) {
                 row -= m_scrolling_region.start;
@@ -1241,7 +1241,7 @@ VteTerminalPrivate::get_cursor_row() const
 vte::grid::column_t
 VteTerminalPrivate::get_cursor_column() const
 {
-        return m_cursor.col;
+        return m_screen->cursor.col;
 }
 
 /*
@@ -1412,12 +1412,12 @@ VteTerminalPrivate::seq_dc()
 
         ensure_cursor_is_onscreen();
 
-        if (_vte_ring_next(m_screen->row_data) > m_cursor.row) {
+        if (_vte_ring_next(m_screen->row_data) > m_screen->cursor.row) {
                long len;
                /* Get the data for the row which the cursor points to. */
-                rowdata = _vte_ring_index_writable(m_screen->row_data, m_cursor.row);
+                rowdata = _vte_ring_index_writable(m_screen->row_data, m_screen->cursor.row);
                g_assert(rowdata != NULL);
-                col = m_cursor.col;
+                col = m_screen->cursor.col;
                len = _vte_row_data_length (rowdata);
                /* Remove the column. */
                if (col < len) {
@@ -1430,7 +1430,7 @@ VteTerminalPrivate::seq_dc()
                        }
                        /* Repaint this row. */
                         invalidate_cells(col, len - col,
-                                         m_cursor.row, 1);
+                                         m_screen->cursor.row, 1);
                }
        }
 
@@ -1476,7 +1476,7 @@ VteTerminalPrivate::seq_cursor_down(vte::grid::row_t rows)
                 end = m_screen->insert_delta + m_row_count - 1;
        }
 
-        m_cursor.row = MIN(m_cursor.row + rows, end);
+        m_screen->cursor.row = MIN(m_screen->cursor.row + rows, end);
 }
 
 /* Erase characters starting at the cursor position (overwriting N with
@@ -1508,14 +1508,14 @@ VteTerminalPrivate::seq_erase_characters(long count)
 
        /* Clear out the given number of characters. */
        auto rowdata = ensure_row();
-        if (_vte_ring_next(m_screen->row_data) > m_cursor.row) {
+        if (_vte_ring_next(m_screen->row_data) > m_screen->cursor.row) {
                g_assert(rowdata != NULL);
                 /* Clean up Tab/CJK fragments. */
-                cleanup_fragments(m_cursor.col, m_cursor.col + count);
+                cleanup_fragments(m_screen->cursor.col, m_screen->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 = m_cursor.col + i;
+                        col = m_screen->cursor.col + i;
                        if (col >= 0) {
                                if (col < (glong) _vte_row_data_length (rowdata)) {
                                        /* Replace this cell with the current
@@ -1529,8 +1529,8 @@ VteTerminalPrivate::seq_erase_characters(long count)
                        }
                }
                /* Repaint this row. */
-                invalidate_cells(m_cursor.col, count,
-                                 m_cursor.row, 1);
+                invalidate_cells(m_screen->cursor.col, count,
+                                 m_screen->cursor.row, 1);
        }
 
        /* We've modified the display.  Make a note of it. */
@@ -1556,9 +1556,9 @@ VteTerminalPrivate::seq_insert_blank_character()
 {
         ensure_cursor_is_onscreen();
 
-        auto save = m_cursor;
+        auto save = m_screen->cursor;
         insert_char(' ', true, true);
-        m_cursor = save;
+        m_screen->cursor = save;
 }
 
 /* Insert N blank characters. */
@@ -1588,9 +1588,9 @@ VteTerminalPrivate::seq_backspace()
 {
         ensure_cursor_is_onscreen();
 
-        if (m_cursor.col > 0) {
+        if (m_screen->cursor.col > 0) {
                /* There's room to move left, so do so. */
-                m_cursor.col--;
+                m_screen->cursor.col--;
        }
 }
 
@@ -1838,7 +1838,7 @@ VteTerminalPrivate::seq_reverse_index()
                 end = start + m_row_count - 1;
        }
 
-        if (m_cursor.row == start) {
+        if (m_screen->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(m_terminal, end);
@@ -1849,7 +1849,7 @@ VteTerminalPrivate::seq_reverse_index()
                                  start, 2);
        } else {
                /* Otherwise, just move the cursor up. */
-                m_cursor.row--;
+                m_screen->cursor.row--;
        }
        /* Adjust the scrollbars if necessary. */
         adjust_adjustments();
@@ -1870,7 +1870,7 @@ VteTerminalPrivate::seq_tab_set()
        if (m_tabstops == NULL) {
                m_tabstops = g_hash_table_new(NULL, NULL);
        }
-       set_tabstop(m_cursor.col);
+       set_tabstop(m_screen->cursor.col);
 }
 
 /* Tab. */
@@ -1887,7 +1887,7 @@ VteTerminalPrivate::seq_tab()
         vte::grid::column_t newcol, col;
 
        /* Calculate which column is the next tab stop. */
-        newcol = col = m_cursor.col;
+        newcol = col = m_screen->cursor.col;
 
        g_assert (col >= 0);
 
@@ -1958,9 +1958,9 @@ VteTerminalPrivate::seq_tab()
                        }
                }
 
-               invalidate_cells(m_cursor.col, newcol - m_cursor.col,
-                                 m_cursor.row, 1);
-                m_cursor.col = newcol;
+               invalidate_cells(m_screen->cursor.col, newcol - m_screen->cursor.col,
+                                 m_screen->cursor.row, 1);
+                m_screen->cursor.col = newcol;
        }
 }
 
@@ -1991,7 +1991,7 @@ void
 VteTerminalPrivate::seq_tab_clear(long param)
 {
        if (param == 0) {
-               clear_tabstop(m_cursor.col);
+               clear_tabstop(m_screen->cursor.col);
        } else if (param == 3) {
                if (m_tabstops != nullptr) {
                        g_hash_table_destroy(m_tabstops);
@@ -2031,7 +2031,7 @@ VteTerminalPrivate::seq_cursor_up(vte::grid::row_t rows)
                start = m_screen->insert_delta;
        }
 
-        m_cursor.row = MAX(m_cursor.row - rows, start);
+        m_screen->cursor.row = MAX(m_screen->cursor.row - rows, start);
 }
 
 /* Vertical tab. */
@@ -2722,7 +2722,7 @@ VteTerminalPrivate::seq_insert_lines(vte::grid::row_t param)
         vte::grid::row_t end, i;
 
        /* Find the region we're messing with. */
-        auto row = m_cursor.row;
+        auto row = m_screen->cursor.row;
         if (m_scrolling_restricted) {
                 end = m_screen->insert_delta + m_scrolling_region.end;
        } else {
@@ -2741,7 +2741,7 @@ VteTerminalPrivate::seq_insert_lines(vte::grid::row_t param)
                 _vte_terminal_ring_remove(m_terminal, end);
                 _vte_terminal_ring_insert(m_terminal, row, TRUE);
        }
-        m_cursor.col = 0;
+        m_screen->cursor.col = 0;
        /* Update the display. */
         scroll_region(row, end - row + 1, param);
        /* Adjust the scrollbars if necessary. */
@@ -2773,7 +2773,7 @@ VteTerminalPrivate::seq_delete_lines(vte::grid::row_t param)
         vte::grid::row_t end, i;
 
        /* Find the region we're messing with. */
-        auto row = m_cursor.row;
+        auto row = m_screen->cursor.row;
         if (m_scrolling_restricted) {
                 end = m_screen->insert_delta + m_scrolling_region.end;
        } else {
@@ -2793,7 +2793,7 @@ VteTerminalPrivate::seq_delete_lines(vte::grid::row_t param)
                 _vte_terminal_ring_remove(m_terminal, row);
                 _vte_terminal_ring_insert(m_terminal, end, TRUE);
        }
-        m_cursor.col = 0;
+        m_screen->cursor.col = 0;
        /* Update the display. */
         scroll_region(row, end - row + 1, -param);
        /* Adjust the scrollbars if necessary. */
@@ -2836,13 +2836,13 @@ VteTerminalPrivate::seq_device_status_report(long param)
                                         rowmax = m_row_count - 1;
                                 }
                                 // FIXMEchpe this looks wrong. shouldn't this first clamp to origin,rowmax 
and *then* subtract origin?
-                                rowval = m_cursor.row - m_screen->insert_delta - origin;
+                                rowval = m_screen->cursor.row - m_screen->insert_delta - origin;
                                 rowval = CLAMP(rowval, 0, rowmax);
                                 char buf[128];
                                 g_snprintf(buf, sizeof(buf),
                                           _VTE_CAP_CSI "%ld;%ldR",
                                            rowval + 1,
-                                           CLAMP(m_cursor.col + 1, 1, m_column_count));
+                                           CLAMP(m_screen->cursor.col + 1, 1, m_column_count));
                                feed_child(buf, -1);
                                break;
                        default:
@@ -2879,13 +2879,13 @@ VteTerminalPrivate::seq_dec_device_status_report(long param)
                                         rowmax = m_row_count - 1;
                                 }
                                 // FIXMEchpe this looks wrong. shouldn't this first clamp to origin,rowmax 
and *then* subtract origin?
-                                rowval = m_cursor.row - m_screen->insert_delta - origin;
+                                rowval = m_screen->cursor.row - m_screen->insert_delta - origin;
                                 rowval = CLAMP(rowval, 0, rowmax);
                                 char buf[128];
                                g_snprintf(buf, sizeof(buf),
                                           _VTE_CAP_CSI "?%ld;%ldR",
                                            rowval + 1,
-                                           CLAMP(m_cursor.col + 1, 1, m_column_count));
+                                           CLAMP(m_screen->cursor.col + 1, 1, m_column_count));
                                feed_child(buf, -1);
                                break;
                        case 15:



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