Commit 430965a0 authored by Paul Bolle's avatar Paul Bolle Committed by Egmont Koblinger

emulation: Add support for DECSCUSR (set cursor style)

https://bugzilla.gnome.org/show_bug.cgi?id=720821
parent 447266e2
......@@ -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")
......
......@@ -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,
......
......@@ -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);
......
......@@ -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)
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment