diff --git a/config.c b/config.c index c3867d2d..707f7d93 100644 --- a/config.c +++ b/config.c @@ -106,6 +106,30 @@ get_config_path(void) return NULL; } +static bool +str_to_color(const char *s, uint32_t *color, const char *path, int lineno) +{ + if (s == NULL) + return false; + + errno = 0; + char *end = NULL; + unsigned long res = strtoul(s, &end, 16); + + if (errno != 0) { + LOG_ERRNO("%s:%d: invalid color: %s", path, lineno, s); + return false; + } + + if (*end != '\0') { + LOG_ERR("%s:%d: invalid color: %s", path, lineno, s); + return false; + } + + *color = res & 0xffffff; + return true; +} + static bool parse_section_main(const char *key, const char *value, struct config *conf, const char *path, unsigned lineno) @@ -163,21 +187,11 @@ parse_section_colors(const char *key, const char *value, struct config *conf, return false; } - errno = 0; - char *end = NULL; - unsigned long res = strtoul(value, &end, 16); - - if (errno != 0) { - LOG_ERRNO("%s:%d: invalid color: %s", path, lineno, value); + uint32_t color_value; + if (!str_to_color(value, &color_value, path, lineno)) return false; - } - if (*end != '\0') { - LOG_ERR("%s:%d: invalid color: %s", path, lineno, value); - return false; - } - - *color = res & 0xffffff; + *color = color_value; return true; } @@ -199,6 +213,26 @@ parse_section_cursor(const char *key, const char *value, struct config *conf, } } + else if (strcmp(key, "color") == 0) { + char *value_copy = strdup(value); + const char *text = strtok(value_copy, " "); + const char *cursor = strtok(NULL, " "); + + uint32_t text_color, cursor_color; + if (text == NULL || cursor == NULL || + !str_to_color(text, &text_color, path, lineno) || + !str_to_color(cursor, &cursor_color, path, lineno)) + { + LOG_ERR("%s:%d: invalid cursor colors: %s", path, lineno, value); + free(value_copy); + return false; + } + + conf->cursor.color.text = 1 << 31 | text_color; + conf->cursor.color.cursor = 1 << 31 | cursor_color; + free(value_copy); + } + else { LOG_ERR("%s:%d: invalid key: %s", path, lineno, key); return false; @@ -388,6 +422,10 @@ config_load(struct config *conf) .cursor = { .style = CURSOR_BLOCK, + .color = { + .text = 0, + .cursor = 0, + }, }, }; diff --git a/config.h b/config.h index 85ce15c1..68d6f0a1 100644 --- a/config.h +++ b/config.h @@ -19,6 +19,10 @@ struct config { struct { enum cursor_style style; + struct { + uint32_t text; + uint32_t cursor; + } color; } cursor; }; diff --git a/main.c b/main.c index 917eec9d..d785024c 100644 --- a/main.c +++ b/main.c @@ -373,6 +373,14 @@ main(int argc, char *const *argv) }, .default_cursor_style = conf.cursor.style, .cursor_style = conf.cursor.style, + .default_cursor_color = { + .text = conf.cursor.color.text, + .cursor = conf.cursor.color.cursor, + }, + .cursor_color = { + .text = conf.cursor.color.text, + .cursor = conf.cursor.color.cursor, + }, .selection = { .start = {-1, -1}, .end = {-1, -1}, diff --git a/render.c b/render.c index 3e5730e0..16bc19b9 100644 --- a/render.c +++ b/render.c @@ -194,6 +194,13 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell, if (cell->attrs.dim) color_dim(&fg); + if (block_cursor && term->cursor_color.text >> 31) { + /* User configured cursor color overrides all attributes */ + assert(term->cursor_color.cursor >> 31); + fg = color_hex_to_rgb(term->cursor_color.text); + bg = color_hex_to_rgb(term->cursor_color.cursor); + } + /* Background */ cairo_set_source_rgb(buf->cairo, bg.r, bg.g, bg.b); cairo_rectangle(buf->cairo, x, y, width, height); @@ -201,11 +208,12 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell, /* Non-block cursors */ if (has_cursor) { + struct rgb cursor_color = color_hex_to_rgb(term->cursor_color.cursor); if (term->cursor_style == CURSOR_BAR) - draw_bar(term, buf, fg, x, y); + draw_bar(term, buf, cursor_color, x, y); else if (term->cursor_style == CURSOR_UNDERLINE) draw_underline( - term, buf, attrs_to_font(term, &cell->attrs), fg, x, y); + term, buf, attrs_to_font(term, &cell->attrs), cursor_color, x, y); } if (cell->attrs.blink && !term->blink.active) { diff --git a/terminal.h b/terminal.h index 94e99215..49a24803 100644 --- a/terminal.h +++ b/terminal.h @@ -296,6 +296,14 @@ struct terminal { enum cursor_style default_cursor_style; enum cursor_style cursor_style; bool cursor_blinking; + struct { + uint32_t text; + uint32_t cursor; + } default_cursor_color; + struct { + uint32_t text; + uint32_t cursor; + } cursor_color; uint32_t input_serial; struct {