summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@src.gnome.org>2002-07-18 23:47:35 +0000
committerNalin Dahyabhai <nalin@src.gnome.org>2002-07-18 23:47:35 +0000
commitc7b0c2bbdb11ea8364829a6a7e0e1c4b0749c4cc (patch)
tree2ee7b600009e97caca9192ea615df6075212483f
parentdfad7e70fef9221c09360fab72998d16f3d23670 (diff)
downloadvte-c7b0c2bbdb11ea8364829a6a7e0e1c4b0749c4cc.tar.gz
Implement enough of set-mode and reset-mode to allow toggling of insertvte_0_5_0
* src/vte.c: Implement enough of set-mode and reset-mode to allow toggling of insert mode using this sequence. Move all scrolling into vte_terminal_scroll_region and use gdk_draw_drawable to avoid repainting from scratch whenever possible.
-rw-r--r--ChangeLog5
-rw-r--r--src/vte.c333
-rw-r--r--vte.spec6
3 files changed, 224 insertions, 120 deletions
diff --git a/ChangeLog b/ChangeLog
index d2ca7696..559ad69f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2002-07-18 nalin
+ * src/vte.c: Implement enough of set-mode and reset-mode to allow
+ toggling of insert mode using this sequence. Move all scrolling into
+ vte_terminal_scroll_region and use gdk_draw_drawable to avoid repainting
+ from scratch whenever possible.
2002-07-17 nalin
* configure.in: Actually set ALL_LINGUAS so translations get installed.
* README: Document the weirdness that is cursor movement around wide
diff --git a/src/vte.c b/src/vte.c
index aea2906c..03044a8a 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -466,6 +466,73 @@ vte_invalidate_all(VteTerminal *terminal)
terminal->row_count);
}
+/* Scroll a rectangular region up or down by a fixed number of lines. */
+static void
+vte_terminal_scroll_region(VteTerminal *terminal,
+ long row, long count, long delta)
+{
+ GtkWidget *widget;
+ VteScreen *screen;
+ GdkGC *gc;
+ gint src_x, src_y, width, height, dest_x, dest_y, w, h;
+ gint refresh_row, refresh_count;
+ gboolean repaint = TRUE;
+
+ if ((delta == 0) || (count == 0)) {
+ /* Shenanigans! */
+ return;
+ }
+
+ /* We only do this if we don't have a background to keep looking right
+ * and if we're not scrolling the entire region. */
+ if (!terminal->pvt->bg_transparent &&
+ (terminal->pvt->bg_image == NULL) &&
+ (MAX(delta, -delta) < count)) {
+ widget = GTK_WIDGET(terminal);
+ gc = widget->style->mid_gc[GTK_WIDGET_STATE(widget)];
+
+ w = terminal->char_width;
+ h = terminal->char_height;
+ screen = terminal->pvt->screen;
+
+ src_x = dest_x = 0;
+ width = w * terminal->column_count;
+ height = h * (count - MAX(delta, -delta));
+
+ if (delta > 0) {
+ src_y = h * (row - screen->scroll_delta);
+ dest_y = src_y + h * delta;
+ refresh_row = row;
+ refresh_count = delta;
+ } else {
+ dest_y = h * (row - screen->scroll_delta);
+ src_y = dest_y + h * (-delta);
+ refresh_row = row + (-delta);
+ refresh_count = count - (-delta);
+ }
+
+ gdk_draw_drawable(widget->window, gc, widget->window,
+ src_x, src_y,
+ dest_x, dest_y,
+ width, height);
+
+ /* Expose the newly-exposed portion of the area. */
+ vte_invalidate_cells(terminal,
+ 0, terminal->column_count,
+ refresh_row, refresh_count);
+
+ /* Don't need to repaint the entire region any more. */
+ repaint = FALSE;
+ }
+
+ if (repaint) {
+ /* We have to repaint the entire area. */
+ vte_invalidate_cells(terminal,
+ 0, terminal->column_count,
+ row, count);
+ }
+}
+
/* Find the character in the given "virtual" position. */
static struct vte_charcell *
vte_terminal_find_charcell(VteTerminal *terminal, long col, long row)
@@ -1420,14 +1487,6 @@ vte_terminal_get_encoding(VteTerminal *terminal)
return terminal->pvt->encoding;
}
-/* Check if we're doing special background effects. */
-static gboolean
-vte_terminal_uses_bgfx(VteTerminal *terminal)
-{
- return ((terminal->pvt->bg_transparent) ||
- (terminal->pvt->bg_image != NULL));
-}
-
/* End alternate character set. */
static void
vte_sequence_handler_ae(VteTerminal *terminal,
@@ -1460,12 +1519,8 @@ vte_sequence_handler_al(VteTerminal *terminal,
}
vte_remove_line_int(terminal, end);
vte_insert_line_int(terminal, start);
- /* Redraw the affected region. */
- if (vte_terminal_uses_bgfx(terminal) || 1) {
- vte_invalidate_cells(terminal,
- 0, terminal->column_count,
- start, end - start + 1);
- }
+ /* Update the display. */
+ vte_terminal_scroll_region(terminal, start, end - start + 1, 1);
}
/* Add N lines at the current cursor position. */
@@ -1922,12 +1977,8 @@ vte_sequence_handler_dl(VteTerminal *terminal,
}
vte_remove_line_int(terminal, start);
vte_insert_line_int(terminal, end);
- /* Redraw the affected region. */
- if (vte_terminal_uses_bgfx(terminal) || 1) {
- vte_invalidate_cells(terminal,
- 0, terminal->column_count,
- start, end - start + 1);
- }
+ /* Update the display. */
+ vte_terminal_scroll_region(terminal, start, end - start + 1, -1);
}
/* Delete N lines at the current cursor position. */
@@ -2017,44 +2068,38 @@ vte_sequence_handler_do(VteTerminal *terminal,
GValueArray *params)
{
GtkWidget *widget;
- long col, row, start, end;
+ long start, end;
VteScreen *screen;
g_return_if_fail(VTE_IS_TERMINAL(terminal));
widget = GTK_WIDGET(terminal);
screen = terminal->pvt->screen;
- start = screen->scrolling_region.start + screen->insert_delta;
- end = screen->scrolling_region.end + screen->insert_delta;
- col = screen->cursor_current.col;
- row = screen->cursor_current.row;
-
if (screen->scrolling_restricted) {
- if (row == end) {
+ start = screen->insert_delta + screen->scrolling_region.start;
+ end = screen->insert_delta + screen->scrolling_region.end;
+ } else {
+ start = screen->scrolling_region.start + screen->insert_delta;
+ end = screen->insert_delta + terminal->row_count - 1;
+ }
+
+ if (screen->cursor_current.row == end) {
+ if (screen->scrolling_restricted) {
/* If we're at the end of the scrolling region, add a
* line at the bottom to scroll the top off. */
vte_remove_line_int(terminal, start);
vte_insert_line_int(terminal, end);
- /* Redraw the affected region. */
- if (vte_terminal_uses_bgfx(terminal) || 1) {
- vte_invalidate_cells(terminal,
- 0,
- terminal->column_count,
- start,
- end - start + 1);
- }
+ /* Update the display. */
+ vte_terminal_scroll_region(terminal, start,
+ end - start + 1, -1);
} else {
- /* Otherwise, just move the cursor down. */
+ /* Scroll up with history. */
screen->cursor_current.row++;
+ vte_terminal_scroll_insertion(terminal);
}
} else {
- /* Move the cursor down. */
+ /* Otherwise, just move the cursor down. */
screen->cursor_current.row++;
-
- /* Adjust the insert delta so that the row the cursor is on
- * is viewable if the insert delta is equal to the scrolling
- * delta. */
- vte_terminal_scroll_insertion(terminal);
}
}
@@ -2739,55 +2784,32 @@ vte_sequence_handler_up(VteTerminal *terminal,
GValueArray *params)
{
GtkWidget *widget;
- long col, row, start, end;
+ long start, end;
VteScreen *screen;
g_return_if_fail(VTE_IS_TERMINAL(terminal));
widget = GTK_WIDGET(terminal);
screen = terminal->pvt->screen;
- col = screen->cursor_current.col;
- row = screen->cursor_current.row;
-
if (screen->scrolling_restricted) {
start = screen->scrolling_region.start + screen->insert_delta;
end = screen->scrolling_region.end + screen->insert_delta;
- if (row == start) {
- /* If we're at the top of the scrolling region, add a
- * line at the top to scroll the bottom off. */
- vte_remove_line_int(terminal, end);
- vte_insert_line_int(terminal, start);
- /* Repaint the affected region. */
- if (vte_terminal_uses_bgfx(terminal) || 1) {
- vte_invalidate_cells(terminal,
- 0, terminal->column_count,
- start, end - start + 1);
- }
- } else {
- /* Otherwise, just move the cursor up. */
- screen->cursor_current.row--;
- row = screen->cursor_current.row;
- }
} else {
start = terminal->pvt->screen->insert_delta;
end = start + terminal->row_count - 1;
- if (row == start) {
- /* Insert a blank line and remove one from the bottom,
- * to simulate a proper scroll without screwing up the
- * history. */
- vte_remove_line_int(terminal, end);
- vte_insert_line_int(terminal, start);
- /* Repaint the affected area. */
- if (vte_terminal_uses_bgfx(terminal) || 1) {
- vte_invalidate_cells(terminal,
- 0, terminal->column_count,
- start, end - start + 1);
- }
- } else {
- /* Move the cursor up. */
- screen->cursor_current.row--;
- row = screen->cursor_current.row;
- }
+ }
+
+ if (screen->cursor_current.row == start) {
+ /* If we're at the top of the scrolling region, add a
+ * line at the top to scroll the bottom off. */
+ vte_remove_line_int(terminal, end);
+ vte_insert_line_int(terminal, start);
+ /* Update the display. */
+ vte_terminal_scroll_region(terminal, start,
+ end - start + 1, 1);
+ } else {
+ /* Otherwise, just move the cursor up. */
+ screen->cursor_current.row--;
}
}
@@ -3496,6 +3518,77 @@ vte_sequence_handler_line_position_absolute(VteTerminal *terminal,
-1, vte_sequence_handler_cv);
}
+/* Toggle a terminal mode. */
+static void
+vte_sequence_handler_set_mode_internal(VteTerminal *terminal,
+ long setting, gboolean value)
+{
+ g_return_if_fail(VTE_IS_TERMINAL(terminal));
+ switch (setting) {
+ case 2: /* keyboard action mode (?) */
+ break;
+ case 4: /* insert/overtype mode */
+ terminal->pvt->screen->insert_mode = value;
+ break;
+ case 12: /* send/receive mode (local echo?) */
+ break;
+ case 20: /* automatic newline / normal linefeed mode */
+ break;
+ default:
+ break;
+ }
+}
+
+/* Set certain terminal attributes. */
+static void
+vte_sequence_handler_set_mode(VteTerminal *terminal,
+ const char *match,
+ GQuark match_quark,
+ GValueArray *params)
+{
+ int i;
+ long setting;
+ GValue *value;
+ g_return_if_fail(VTE_IS_TERMINAL(terminal));
+ if ((params == NULL) || (params->n_values == 0)) {
+ return;
+ }
+ for (i = 0; i < params->n_values; i++) {
+ value = g_value_array_get_nth(params, i);
+ if (!G_VALUE_HOLDS_LONG(value)) {
+ continue;
+ }
+ setting = g_value_get_long(value);
+ vte_sequence_handler_set_mode_internal(terminal, setting,
+ TRUE);
+ }
+}
+
+/* Unset certain terminal attributes. */
+static void
+vte_sequence_handler_reset_mode(VteTerminal *terminal,
+ const char *match,
+ GQuark match_quark,
+ GValueArray *params)
+{
+ int i;
+ long setting;
+ GValue *value;
+ g_return_if_fail(VTE_IS_TERMINAL(terminal));
+ if ((params == NULL) || (params->n_values == 0)) {
+ return;
+ }
+ for (i = 0; i < params->n_values; i++) {
+ value = g_value_array_get_nth(params, i);
+ if (!G_VALUE_HOLDS_LONG(value)) {
+ continue;
+ }
+ setting = g_value_get_long(value);
+ vte_sequence_handler_set_mode_internal(terminal, setting,
+ FALSE);
+ }
+}
+
/* Set certain terminal attributes. */
static void
vte_sequence_handler_decset(VteTerminal *terminal,
@@ -3661,23 +3754,23 @@ vte_sequence_handler_insert_lines(VteTerminal *terminal,
value = g_value_array_get_nth(params, 0);
param = g_value_get_long(value);
}
+ /* Find the region we're messing with. */
row = screen->cursor_current.row;
- end = screen->scrolling_region.end + screen->insert_delta;
+ if (screen->scrolling_restricted) {
+ end = screen->scrolling_region.end + screen->insert_delta;
+ } else {
+ end = screen->insert_delta + terminal->row_count - 1;
+ }
/* Insert the new lines at the cursor. */
for (i = 0; i < param; i++) {
- /* Clear lines off the bottom of the scrolling region. */
- if (screen->scrolling_restricted) {
- /* Clear a line off the end of the region. */
- vte_remove_line_int(terminal, end);
- }
+ /* Clear a line off the end of the region and add one to the
+ * top of the region. */
+ vte_remove_line_int(terminal, end);
vte_insert_line_int(terminal, row);
}
- /* Refresh the modified area. */
- if (vte_terminal_uses_bgfx(terminal) || 1) {
- vte_invalidate_cells(terminal,
- 0, terminal->column_count,
- row, end - row + 1);
- }
+ /* Update the display. */
+ vte_terminal_scroll_region(terminal, row,
+ end - row + 1, param);
}
/* Delete certain lines from the scrolling region. */
@@ -3700,24 +3793,23 @@ vte_sequence_handler_delete_lines(VteTerminal *terminal,
value = g_value_array_get_nth(params, 0);
param = g_value_get_long(value);
}
- /* Clear the lines which we need to clear. */
+ /* Find the region we're messing with. */
row = screen->cursor_current.row;
- end = screen->insert_delta + screen->scrolling_region.end;
+ if (screen->scrolling_restricted) {
+ end = screen->scrolling_region.end + screen->insert_delta;
+ } else {
+ end = screen->insert_delta + terminal->row_count - 1;
+ }
/* Clear them from below the current cursor. */
for (i = 0; i < param; i++) {
- /* Insert any new empty lines. */
- if (screen->scrolling_restricted) {
- vte_insert_line_int(terminal, end);
- }
- /* Remove the line at the top of the area. */
+ /* Insert a line at the end of the region and remove one from
+ * the top of the region. */
+ vte_insert_line_int(terminal, end);
vte_remove_line_int(terminal, row);
}
- /* Refresh the modified area. */
- if (vte_terminal_uses_bgfx(terminal) || 1) {
- vte_invalidate_cells(terminal,
- 0, terminal->column_count,
- row, end - row + 1);
- }
+ /* Update the display. */
+ vte_terminal_scroll_region(terminal, row,
+ end - row + 1, -param);
}
/* Index. Move the cursor down a row, and if it's in a scrolling region,
@@ -4691,7 +4783,7 @@ static struct {
{"repeat", NULL},
{"request-locator-position", NULL},
{"request-terminal-parameters", NULL},
- {"reset-mode", NULL},
+ {"reset-mode", vte_sequence_handler_reset_mode},
{"restore-cursor", vte_sequence_handler_rc},
{"restore-mode", vte_sequence_handler_restore_mode},
{"return-terminal-id", NULL},
@@ -4710,7 +4802,7 @@ static struct {
{"set-conformance-level", NULL},
{"set-icon-and-window-title", vte_sequence_handler_set_icon_and_window_title},
{"set-icon-title", vte_sequence_handler_set_icon_title},
- {"set-mode", NULL},
+ {"set-mode", vte_sequence_handler_set_mode},
{"set-scrolling-region", vte_sequence_handler_set_scrolling_region},
{"set-window-title", vte_sequence_handler_set_window_title},
{"single-shift-g2", NULL},
@@ -4757,7 +4849,6 @@ vte_terminal_set_color_int(VteTerminal *terminal, int entry,
gvisual = gtk_widget_get_visual(widget);
visual = gdk_x11_visual_get_xvisual(gvisual);
-
/* Create a working copy of what we want, which GDK will
* adjust below when it fills in the pixel value. */
color = *proposed;
@@ -7322,12 +7413,14 @@ vte_terminal_get_text(VteTerminal *terminal,
/* Stuff any saved spaces in. */
while (spaces > 0) {
string = g_string_append_c(string, ' ');
- --spaces;
+ spaces--;
}
/* Stuff the character in this cell. */
string = g_string_append_unichar(string, pcell->c);
}
}
+ /* If we added a character to the string, record its
+ * attributes, one per byte. */
if (attributes) {
while (attributes->len < string->len) {
g_array_append_val(attributes, attr);
@@ -7335,6 +7428,16 @@ vte_terminal_get_text(VteTerminal *terminal,
}
x++;
} while (pcell != NULL);
+ /* If we broke out of the loop, there might be more characters
+ * with missing attributes. */
+ if (attributes) {
+ while (attributes->len < string->len) {
+ g_array_append_val(attributes, attr);
+ }
+ }
+ }
+ if (attributes) {
+ g_assert(string->len == attributes->len);
}
return g_string_free(string, FALSE);
}
@@ -8480,18 +8583,8 @@ vte_handle_scroll(VteTerminal *terminal)
dy = screen->scroll_delta - adj;
screen->scroll_delta = adj;
if (dy != 0) {
- if (vte_terminal_uses_bgfx(terminal)) {
- /* If we have a background image, we need to redraw
- * the entire window. */
- vte_invalidate_all(terminal);
- } else {
- /* Scroll whatever's already in the window to avoid
- * redrawing as much as possible -- any exposed area
- * will be exposed for us by the windowing system
- * and GDK. */
- gdk_window_scroll(widget->window,
- 0, dy * terminal->char_height);
- }
+ vte_terminal_scroll_region(terminal, screen->scroll_delta,
+ terminal->row_count, dy);
}
/* Let the refreshing begin. */
gdk_window_thaw_updates(widget->window);
diff --git a/vte.spec b/vte.spec
index 10f9754d..48925b5d 100644
--- a/vte.spec
+++ b/vte.spec
@@ -58,6 +58,12 @@ make install DESTDIR=$RPM_BUILD_ROOT
%{_libdir}/pkgconfig/*
%changelog
+* Thu Jul 18 2002 Nalin Dahyabhai <nalin@redhat.com> 0.5.0-1
+- use gunichars internally
+- scroll regions more effectively
+- implement part of set-mode/reset-mode (maybe fixes #69143)
+- fix corner case in dingus hiliting (#67930, really this time)
+
* Tue Jul 16 2002 Nalin Dahyabhai <nalin@redhat.com> 0.4.9-1
- check for iconv failures properly and report them more aggressively
- guess at a proper default bold color (#68965)