From 27d2fcf721de6ac698cd61192cb1934864f414aa Mon Sep 17 00:00:00 2001 From: Will Corvo Date: Sun, 6 Sep 2026 02:38:35 +0300 Subject: [PATCH] cursor blinking rate feature --- src/tsm/libtsm-int.h | 1 + src/tsm/libtsm.h | 3 +++ src/tsm/libtsm.sym | 6 ++++++ src/tsm/tsm-screen.c | 24 ++++++++++++++++++++++++ src/tsm/tsm-vte.c | 5 +++++ 5 files changed, 39 insertions(+) diff --git a/src/tsm/libtsm-int.h b/src/tsm/libtsm-int.h index 19cee5b..9f87912 100644 --- a/src/tsm/libtsm-int.h +++ b/src/tsm/libtsm-int.h @@ -149,6 +149,7 @@ struct tsm_screen { unsigned int cursor_y; /* current cursor y-pos */ enum tsm_screen_cursor_style cstyle; /* cursor shape */ + uint32_t blinking_rate_ms; /* cursor blinking rate */ /* tab ruler */ bool *tab_ruler; /* tab-flag for all cells of one row */ diff --git a/src/tsm/libtsm.h b/src/tsm/libtsm.h index 2659da1..d6fd35e 100644 --- a/src/tsm/libtsm.h +++ b/src/tsm/libtsm.h @@ -309,6 +309,9 @@ const struct tsm_screen_cell *tsm_screen_draw2(struct tsm_screen *con); enum tsm_screen_cursor_style tsm_screen_get_cursor_style(struct tsm_screen *con); void tsm_screen_set_cursor_style(struct tsm_screen *con, enum tsm_screen_cursor_style type); +uint32_t tsm_screen_get_cursor_blinking_rate_ms(struct tsm_screen *con); +void tsm_screen_set_cursor_blinking_rate_ms(struct tsm_screen *con, uint32_t ms); + /** @} */ /** diff --git a/src/tsm/libtsm.sym b/src/tsm/libtsm.sym index 7869144..b51302c 100644 --- a/src/tsm/libtsm.sym +++ b/src/tsm/libtsm.sym @@ -159,3 +159,9 @@ global: tsm_screen_get_cursor_style; tsm_screen_set_cursor_style; } LIBTSM_4_6; + +LIBTSM_4_8 { +global: + tsm_screen_get_cursor_blinking_rate_ms; + tsm_screen_set_cursor_blinking_rate_ms; +} LIBTSM_4_7; diff --git a/src/tsm/tsm-screen.c b/src/tsm/tsm-screen.c index bf37bad..407fcee 100644 --- a/src/tsm/tsm-screen.c +++ b/src/tsm/tsm-screen.c @@ -483,6 +483,7 @@ int tsm_screen_new(struct tsm_screen **out, tsm_log_t log, void *log_data) con->def_attr.fr = 255; con->def_attr.fg = 255; con->def_attr.fb = 255; + con->blinking_rate_ms = 500; shl_dlist_init(&con->sb.list); ret = tsm_symbol_table_new(&con->sym_table); @@ -1690,3 +1691,26 @@ void tsm_screen_set_cursor_style(struct tsm_screen *con, enum tsm_screen_cursor_ con->cstyle = type; } + +SHL_EXPORT +uint32_t tsm_screen_get_cursor_blinking_rate_ms(struct tsm_screen *con) +{ + if (!con) + return 0; + + return con->blinking_rate_ms; +} + +SHL_EXPORT +void tsm_screen_set_cursor_blinking_rate_ms(struct tsm_screen *con, uint32_t ms) +{ + if (!con) + return; + + if (ms < 50) + ms = 50; + if (ms > 5000) + ms = 5000; + + con->blinking_rate_ms = ms; +} diff --git a/src/tsm/tsm-vte.c b/src/tsm/tsm-vte.c index f154782..204e224 100644 --- a/src/tsm/tsm-vte.c +++ b/src/tsm/tsm-vte.c @@ -2171,6 +2171,11 @@ static void do_csi(struct tsm_vte *vte, uint32_t data) vte->led_cb(vte, vte->led_state, vte->led_data); } break; + case ']': /* Cursor blinking rate */ + /* This behavior is similar to agetty */ + if (vte->csi_argv[0] == 16 && vte->csi_argc >= 2) + tsm_screen_set_cursor_blinking_rate_ms(vte->con, vte->csi_argv[1]); + break; default: llog_debug(vte, "unhandled CSI sequence %c", data); }