diff --git a/src/caps.c b/src/caps.c
index 7f20bc3..33f20bb 100644
--- a/src/caps.c
+++ b/src/caps.c
@@ -495,6 +495,7 @@ struct _vte_capability_string _vte_xterm_capability_strings[] = {
 	{CSI "?%dn", "dec-device-status-report", 0},
 	{CSI "!p", "soft-reset", 0},
 	{CSI "%d;%d\"p", "set-conformance-level", 0},
+	{CSI "%d q", "set-cursor-style", 0}, /* DECSCUSR */
 	{CSI "%d\"q", "select-character-protection", 0},
 
 	{CSI "r", "set-scrolling-region", 0},
diff --git a/src/vte-private.h b/src/vte-private.h
index b7de21f..a4f138f 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -147,6 +147,29 @@ typedef struct _VteVisualPosition {
 	long row, col;
 } VteVisualPosition;
 
+/* 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,
+	VTE_CURSOR_STYLE_BLINK_BLOCK,
+	VTE_CURSOR_STYLE_STEADY_BLOCK,
+	VTE_CURSOR_STYLE_BLINK_UNDERLINE,
+	VTE_CURSOR_STYLE_STEADY_UNDERLINE,
+	/* *_IBEAM are xterm extensions */
+	VTE_CURSOR_STYLE_BLINK_IBEAM,
+	VTE_CURSOR_STYLE_STEADY_IBEAM
+} VteCursorStyle;
+
 /* Terminal private data. */
 struct _VteTerminalPrivate {
 	/* Emulation setup data. */
@@ -287,6 +310,9 @@ struct _VteTerminalPrivate {
 	gboolean alternate_screen_scroll;
 	long scrollback_lines;
 
+	/* DECSCUSR cursor style */
+	VteCursorStyle cursor_style;
+
 	/* Cursor shape */
 	VteTerminalCursorShape cursor_shape;
         float cursor_aspect_ratio;
@@ -453,6 +479,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_s,
diff --git a/src/vte.c b/src/vte.c
index 0f58d12..67a9b6c 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -141,6 +141,8 @@ 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 VteTerminalCursorShape _vte_terminal_decscusr_cursor_shape(VteTerminal *terminal);
+static VteTerminalCursorBlinkMode _vte_terminal_decscusr_cursor_blink(VteTerminal *terminal);
 static void vte_terminal_set_font_full_internal(VteTerminal *terminal,
                                                 const PangoFontDescription *font_desc,
                                                 VteTerminalAntiAlias antialias);
@@ -8512,6 +8514,9 @@ vte_terminal_init(VteTerminal *terminal)
 	pvt->nrc_mode = TRUE;
 	vte_terminal_set_default_tabstops(terminal);
 
+	/* DECSCUSR cursor style */
+	pvt->cursor_style = VTE_CURSOR_STYLE_TERMINAL_DEFAULT;
+
 	/* Cursor shape. */
 	pvt->cursor_shape = VTE_CURSOR_SHAPE_BLOCK;
         pvt->cursor_aspect_ratio = 0.04;
@@ -10985,7 +10990,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;
@@ -13705,7 +13710,7 @@ vte_terminal_set_cursor_blink_mode(VteTerminal *terminal, VteTerminalCursorBlink
 
         pvt->cursor_blink_mode = mode;
 
-        switch (mode) {
+        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", &blinks,
@@ -13787,6 +13792,106 @@ vte_terminal_get_cursor_shape(VteTerminal *terminal)
 }
 
 /**
+ * _vte_terminal_set_cursor_style:
+ * @terminal: a #VteTerminal
+ * @shape: the #VteTerminalCursorShape to use
+ *
+ * DECSCUSR (Set cursor style).
+ *
+ * Since: 0.36
+ */
+void
+_vte_terminal_set_cursor_style(VteTerminal *terminal, VteCursorStyle style)
+{
+        VteTerminalPrivate *pvt;
+	gboolean blinks;
+
+	g_return_if_fail(VTE_IS_TERMINAL(terminal));
+	pvt = terminal->pvt;
+
+	if (pvt->cursor_style == style)
+		return;
+
+	pvt->cursor_style = style;
+
+	/* update cursor blink to match the DECSCUSR style */
+	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",
+						     &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);
+
+	/* 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
+ * currently set cursor blink mode. Internal use only.
+ *
+ * Return value: cursor blink mode
+ */
+static VteTerminalCursorBlinkMode
+_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 currently
+ * set cursor shape. Internal use only.
+ *
+ * Return value: cursor shape
+ */
+static VteTerminalCursorShape
+_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
  * @lines: the length of the history buffer
diff --git a/src/vteseq-n.gperf b/src/vteseq-n.gperf
index 197183e..9ed1b66 100644
--- a/src/vteseq-n.gperf
+++ b/src/vteseq-n.gperf
@@ -69,6 +69,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(vte_sequence_handler_cursor_lower_left)
 "delete-characters", VTE_SEQUENCE_HANDLER(vte_sequence_handler_DC)
 "application-keypad", VTE_SEQUENCE_HANDLER(vte_sequence_handler_application_keypad)
diff --git a/src/vteseq.c b/src/vteseq.c
index dc82792..4ec6ae3 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -3177,6 +3177,31 @@ 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);
+	}
+
+	_vte_terminal_set_cursor_style(terminal, style);
+}
+
 /* Perform a soft reset. */
 static void
 vte_sequence_handler_soft_reset (VteTerminal *terminal, GValueArray *params)
