[vte] emulation: Add support for DECSCUSR (set cursor style)
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] emulation: Add support for DECSCUSR (set cursor style)
- Date: Sat, 22 Nov 2014 14:46:04 +0000 (UTC)
commit 430965a0bc372296555f859bcf56a358ea191507
Author: Paul Bolle <pebolle tiscali nl>
Date: Sat Nov 22 15:45:19 2014 +0100
emulation: Add support for DECSCUSR (set cursor style)
https://bugzilla.gnome.org/show_bug.cgi?id=720821
src/caps.c | 2 +
src/vte-private.h | 33 +++++++++++++-
src/vte.c | 127 +++++++++++++++++++++++++++++++++++++++++++---------
src/vteseq-n.gperf | 1 +
src/vteseq.c | 28 +++++++++++
5 files changed, 167 insertions(+), 24 deletions(-)
---
diff --git a/src/caps.c b/src/caps.c
index e6c235c..7ace1ad 100644
--- a/src/caps.c
+++ b/src/caps.c
@@ -190,6 +190,8 @@ const char _vte_xterm_capability_strings[] =
ENTRY(CSI "?%dn", "dec-device-status-report")
ENTRY(CSI "!p", "soft-reset")
ENTRY(CSI "%d;%d\"p", "set-conformance-level")
+ ENTRY(CSI " q", "set-cursor-style")
+ ENTRY(CSI "%d q", "set-cursor-style")
ENTRY(CSI "%d\"q", "select-character-protection")
ENTRY(CSI "r", "set-scrolling-region")
diff --git a/src/vte-private.h b/src/vte-private.h
index 1eb86a6..ca10c2e 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -165,6 +165,29 @@ typedef struct _VtePaletteColor {
} sources[2];
} VtePaletteColor;
+/* These correspond to the parameters for DECSCUSR (Set cursor style). */
+typedef enum _VteCursorStyle {
+ /* We treat 0 and 1 differently, assuming that the VT510 does so too.
+ *
+ * See, according to the "VT510 Video Terminal Programmer Information",
+ * from vt100.net, paragraph "2.5.7 Cursor Display", there was a menu
+ * item in the "Terminal Set-Up" to set the cursor's style. It looks
+ * like that defaulted to blinking block. So it makes sense for 0 to
+ * mean "set cursor style to default (set by Set-Up)" and 1 to mean
+ * "set cursor style to blinking block", since that default need not be
+ * blinking block. Access to a VT510 is needed to test this theory,
+ * but it seems plausible. And, anyhow, we can even decide we know
+ * better than the VT510 designers! */
+ VTE_CURSOR_STYLE_TERMINAL_DEFAULT = 0,
+ VTE_CURSOR_STYLE_BLINK_BLOCK = 1,
+ VTE_CURSOR_STYLE_STEADY_BLOCK = 2,
+ VTE_CURSOR_STYLE_BLINK_UNDERLINE = 3,
+ VTE_CURSOR_STYLE_STEADY_UNDERLINE = 4,
+ /* *_IBEAM are xterm extensions */
+ VTE_CURSOR_STYLE_BLINK_IBEAM = 5,
+ VTE_CURSOR_STYLE_STEADY_IBEAM = 6
+} VteCursorStyle;
+
/* Terminal private data. */
struct _VteTerminalPrivate {
/* Metric and sizing data: dimensions of the window */
@@ -286,11 +309,11 @@ struct _VteTerminalPrivate {
gboolean alternate_screen_scroll;
long scrollback_lines;
- /* Cursor shape */
+ /* Cursor shape, as set via API */
VteCursorShape cursor_shape;
float cursor_aspect_ratio;
- /* Cursor blinking. */
+ /* Cursor blinking, as set in dconf. */
VteCursorBlinkMode cursor_blink_mode;
gboolean cursor_blink_state;
guint cursor_blink_tag; /* cursor blinking timeout ID */
@@ -301,6 +324,10 @@ struct _VteTerminalPrivate {
gboolean cursor_visible;
gboolean has_focus; /* is the terminal window focused */
+ /* DECSCUSR cursor style (shape and blinking possibly overridden
+ * via escape sequence) */
+ VteCursorStyle cursor_style;
+
/* Input device options. */
gboolean input_enabled;
time_t last_keypress_time;
@@ -450,6 +477,8 @@ VteRowData *_vte_terminal_ring_insert (VteTerminal *terminal, glong position, gb
VteRowData *_vte_terminal_ring_append (VteTerminal *terminal, gboolean fill);
void _vte_terminal_ring_remove (VteTerminal *terminal, glong position);
+void _vte_terminal_set_cursor_style(VteTerminal *terminal, VteCursorStyle style);
+
/* vteseq.c: */
void _vte_terminal_handle_sequence(VteTerminal *terminal,
const char *match,
diff --git a/src/vte.c b/src/vte.c
index aca4195..a018cd1 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -132,8 +132,10 @@ static void vte_terminal_add_process_timeout (VteTerminal *terminal);
static void add_update_timeout (VteTerminal *terminal);
static void remove_update_timeout (VteTerminal *terminal);
static void reset_update_regions (VteTerminal *terminal);
-static void vte_terminal_set_cursor_blinks_internal(VteTerminal *terminal, gboolean blink);
+static void vte_terminal_update_cursor_blinks_internal(VteTerminal *terminal);
static void _vte_check_cursor_blink(VteTerminal *terminal);
+static VteCursorShape _vte_terminal_decscusr_cursor_shape(VteTerminal *terminal);
+static VteCursorBlinkMode _vte_terminal_decscusr_cursor_blink(VteTerminal *terminal);
static gboolean process_timeout (gpointer data);
static gboolean update_timeout (gpointer data);
@@ -8029,6 +8031,10 @@ vte_terminal_init(VteTerminal *terminal)
pvt->cursor_blinks = FALSE;
pvt->cursor_blink_mode = VTE_CURSOR_BLINK_SYSTEM;
+ /* DECSCUSR cursor style (shape and blinking possibly overridden
+ * via escape sequence) */
+ pvt->cursor_style = VTE_CURSOR_STYLE_TERMINAL_DEFAULT;
+
/* Matching data. */
pvt->match_regexes = g_array_new(FALSE, TRUE,
sizeof(struct vte_match_regex));
@@ -8291,8 +8297,7 @@ vte_terminal_sync_settings (GtkSettings *settings,
pvt->cursor_blink_cycle = blink_time / 2;
pvt->cursor_blink_timeout = blink_timeout;
- if (pvt->cursor_blink_mode == VTE_CURSOR_BLINK_SYSTEM)
- vte_terminal_set_cursor_blinks_internal(terminal, blink);
+ vte_terminal_update_cursor_blinks_internal(terminal);
}
static void
@@ -9555,7 +9560,7 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
x = item.x;
y = item.y;
- switch (terminal->pvt->cursor_shape) {
+ switch (_vte_terminal_decscusr_cursor_shape(terminal)) {
case VTE_CURSOR_SHAPE_IBEAM: {
int stem_width;
@@ -11330,11 +11335,25 @@ vte_terminal_get_has_selection(VteTerminal *terminal)
}
static void
-vte_terminal_set_cursor_blinks_internal(VteTerminal *terminal, gboolean blink)
+vte_terminal_update_cursor_blinks_internal(VteTerminal *terminal)
{
VteTerminalPrivate *pvt = terminal->pvt;
+ gboolean blink = FALSE;
+
+ switch (_vte_terminal_decscusr_cursor_blink(terminal)) {
+ case VTE_CURSOR_BLINK_SYSTEM:
+ g_object_get(gtk_widget_get_settings(GTK_WIDGET(terminal)),
+ "gtk-cursor-blink",
+ &blink, NULL);
+ break;
+ case VTE_CURSOR_BLINK_ON:
+ blink = TRUE;
+ break;
+ case VTE_CURSOR_BLINK_OFF:
+ blink = FALSE;
+ break;
+ }
- blink = !!blink;
if (pvt->cursor_blinks == blink)
return;
@@ -11354,7 +11373,6 @@ void
vte_terminal_set_cursor_blink_mode(VteTerminal *terminal, VteCursorBlinkMode mode)
{
VteTerminalPrivate *pvt;
- gboolean blinks;
g_return_if_fail(VTE_IS_TERMINAL(terminal));
pvt = terminal->pvt;
@@ -11364,21 +11382,7 @@ vte_terminal_set_cursor_blink_mode(VteTerminal *terminal, VteCursorBlinkMode mod
pvt->cursor_blink_mode = mode;
- switch (mode) {
- case VTE_CURSOR_BLINK_SYSTEM:
- g_object_get(gtk_widget_get_settings(GTK_WIDGET(terminal)),
- "gtk-cursor-blink", &blinks,
- NULL);
- break;
- case VTE_CURSOR_BLINK_ON:
- blinks = TRUE;
- break;
- case VTE_CURSOR_BLINK_OFF:
- blinks = FALSE;
- break;
- }
-
- vte_terminal_set_cursor_blinks_internal(terminal, blinks);
+ vte_terminal_update_cursor_blinks_internal(terminal);
g_object_notify(G_OBJECT(terminal), "cursor-blink-mode");
}
@@ -11439,6 +11443,83 @@ vte_terminal_get_cursor_shape(VteTerminal *terminal)
return terminal->pvt->cursor_shape;
}
+/* DECSCUSR set cursor style */
+void
+_vte_terminal_set_cursor_style(VteTerminal *terminal, VteCursorStyle style)
+{
+ VteTerminalPrivate *pvt;
+
+ g_return_if_fail(VTE_IS_TERMINAL(terminal));
+ pvt = terminal->pvt;
+
+ if (pvt->cursor_style == style)
+ return;
+
+ pvt->cursor_style = style;
+
+ vte_terminal_update_cursor_blinks_internal(terminal);
+
+ /* and this will also make cursor shape match the DECSCUSR style */
+ _vte_invalidate_cursor_once(terminal, FALSE);
+}
+
+/*
+ * _vte_terminal_decscusr_cursor_blink:
+ * @terminal: a #VteTerminal
+ *
+ * Returns the cursor blink mode set by DECSCUSR. If DECSCUSR was never
+ * called, or it set the blink mode to terminal default, this returns the
+ * value set via API or in dconf. Internal use only.
+ *
+ * Return value: cursor blink mode
+ */
+static VteCursorBlinkMode
+_vte_terminal_decscusr_cursor_blink(VteTerminal *terminal)
+{
+ switch (terminal->pvt->cursor_style) {
+ default:
+ case VTE_CURSOR_STYLE_TERMINAL_DEFAULT:
+ return terminal->pvt->cursor_blink_mode;
+ case VTE_CURSOR_STYLE_BLINK_BLOCK:
+ case VTE_CURSOR_STYLE_BLINK_UNDERLINE:
+ case VTE_CURSOR_STYLE_BLINK_IBEAM:
+ return VTE_CURSOR_BLINK_ON;
+ case VTE_CURSOR_STYLE_STEADY_BLOCK:
+ case VTE_CURSOR_STYLE_STEADY_UNDERLINE:
+ case VTE_CURSOR_STYLE_STEADY_IBEAM:
+ return VTE_CURSOR_BLINK_OFF;
+ }
+}
+
+/*
+ * _vte_terminal_decscusr_cursor_shape:
+ * @terminal: a #VteTerminal
+ *
+ * Returns the cursor shape set by DECSCUSR. If DECSCUSR was never called,
+ * or it set the cursor shape to terminal default, this returns the value
+ * set via API. Internal use only.
+ *
+ * Return value: cursor shape
+ */
+static VteCursorShape
+_vte_terminal_decscusr_cursor_shape(VteTerminal *terminal)
+{
+ switch (terminal->pvt->cursor_style) {
+ default:
+ case VTE_CURSOR_STYLE_TERMINAL_DEFAULT:
+ return terminal->pvt->cursor_shape;
+ case VTE_CURSOR_STYLE_BLINK_BLOCK:
+ case VTE_CURSOR_STYLE_STEADY_BLOCK:
+ return VTE_CURSOR_SHAPE_BLOCK;
+ case VTE_CURSOR_STYLE_BLINK_UNDERLINE:
+ case VTE_CURSOR_STYLE_STEADY_UNDERLINE:
+ return VTE_CURSOR_SHAPE_UNDERLINE;
+ case VTE_CURSOR_STYLE_BLINK_IBEAM:
+ case VTE_CURSOR_STYLE_STEADY_IBEAM:
+ return VTE_CURSOR_SHAPE_IBEAM;
+ }
+}
+
/**
* vte_terminal_set_scrollback_lines:
* @terminal: a #VteTerminal
@@ -11715,6 +11796,8 @@ vte_terminal_reset(VteTerminal *terminal,
vte_terminal_queue_adjustment_value_changed (terminal, 0);
_vte_terminal_adjust_adjustments_full (terminal);
}
+ /* DECSCUSR cursor style */
+ pvt->cursor_style = VTE_CURSOR_STYLE_TERMINAL_DEFAULT;
/* Do more stuff we refer to as a "full" reset. */
if (clear_tabstops) {
vte_terminal_set_default_tabstops(terminal);
diff --git a/src/vteseq-n.gperf b/src/vteseq-n.gperf
index 208ab19..424a05d 100644
--- a/src/vteseq-n.gperf
+++ b/src/vteseq-n.gperf
@@ -75,6 +75,7 @@ struct vteseq_n_struct {
"erase-characters", VTE_SEQUENCE_HANDLER(vte_sequence_handler_erase_characters)
"erase-in-display", VTE_SEQUENCE_HANDLER(vte_sequence_handler_erase_in_display)
"set-window-title", VTE_SEQUENCE_HANDLER(vte_sequence_handler_set_window_title)
+"set-cursor-style", VTE_SEQUENCE_HANDLER(vte_sequence_handler_set_cursor_style)
#"cursor-lower-left", VTE_SEQUENCE_HANDLER_NULL
"delete-characters", VTE_SEQUENCE_HANDLER(vte_sequence_handler_delete_characters)
"application-keypad", VTE_SEQUENCE_HANDLER(vte_sequence_handler_application_keypad)
diff --git a/src/vteseq.c b/src/vteseq.c
index 4d21f9f..a5726e3 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -2787,6 +2787,34 @@ vte_sequence_handler_screen_alignment_test (VteTerminal *terminal, GValueArray *
terminal->pvt->text_modified_flag = TRUE;
}
+/* DECSCUSR set cursor style */
+static void
+vte_sequence_handler_set_cursor_style (VteTerminal *terminal, GValueArray *params)
+{
+ long style;
+
+ if ((params == NULL) || (params->n_values > 1)) {
+ return;
+ }
+
+ if (params->n_values == 0) {
+ /* no parameters means default (according to vt100.net) */
+ style = VTE_CURSOR_STYLE_TERMINAL_DEFAULT;
+ } else {
+ GValue *value = g_value_array_get_nth(params, 0);
+
+ if (!G_VALUE_HOLDS_LONG(value)) {
+ return;
+ }
+ style = g_value_get_long(value);
+ if (style < 0 || style > 6) {
+ return;
+ }
+ }
+
+ _vte_terminal_set_cursor_style(terminal, style);
+}
+
/* Perform a soft reset. */
static void
vte_sequence_handler_soft_reset (VteTerminal *terminal, GValueArray *params)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]