Merge branch 'config-color'

This commit is contained in:
Daniel Eklöf 2019-07-21 11:34:45 +02:00
commit 07b3e76062
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
7 changed files with 203 additions and 97 deletions

124
config.c
View file

@ -16,6 +16,31 @@
#define LOG_ENABLE_DBG 0 #define LOG_ENABLE_DBG 0
#include "log.h" #include "log.h"
static const uint32_t default_foreground = 0xdcdccc;
static const uint32_t default_background = 0x111111;
static const uint32_t default_regular[] = {
0x000000,
0xcc9393,
0x7f9f7f,
0xd0bf8f,
0x6ca0a3,
0xdc8cc3,
0x93e0e3,
0xdcdccc,
};
static const uint32_t default_bright[] = {
0x000000,
0xdca3a3,
0xbfebbf,
0xf0dfaf,
0x8cd0d3,
0xdc8cc3,
0x93e0e3,
0xffffff,
};
static char * static char *
get_shell(void) get_shell(void)
{ {
@ -108,11 +133,60 @@ parse_section_main(const char *key, const char *value, struct config *conf,
return true; return true;
} }
static bool
parse_section_colors(const char *key, const char *value, struct config *conf,
const char *path, unsigned lineno)
{
uint32_t *color = NULL;
if (strcmp(key, "foreground") == 0) color = &conf->colors.fg;
else if (strcmp(key, "background") == 0) color = &conf->colors.bg;
else if (strcmp(key, "regular0") == 0) color = &conf->colors.regular[0];
else if (strcmp(key, "regular1") == 0) color = &conf->colors.regular[1];
else if (strcmp(key, "regular2") == 0) color = &conf->colors.regular[2];
else if (strcmp(key, "regular3") == 0) color = &conf->colors.regular[3];
else if (strcmp(key, "regular4") == 0) color = &conf->colors.regular[4];
else if (strcmp(key, "regular5") == 0) color = &conf->colors.regular[5];
else if (strcmp(key, "regular6") == 0) color = &conf->colors.regular[6];
else if (strcmp(key, "regular7") == 0) color = &conf->colors.regular[7];
else if (strcmp(key, "bright0") == 0) color = &conf->colors.bright[0];
else if (strcmp(key, "bright1") == 0) color = &conf->colors.bright[1];
else if (strcmp(key, "bright2") == 0) color = &conf->colors.bright[2];
else if (strcmp(key, "bright3") == 0) color = &conf->colors.bright[3];
else if (strcmp(key, "bright4") == 0) color = &conf->colors.bright[4];
else if (strcmp(key, "bright5") == 0) color = &conf->colors.bright[5];
else if (strcmp(key, "bright6") == 0) color = &conf->colors.bright[6];
else if (strcmp(key, "bright7") == 0) color = &conf->colors.bright[7];
else {
LOG_ERR("%s:%d: invalid key: %s", path, lineno, key);
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);
return false;
}
if (*end != '\0') {
LOG_ERR("%s:%d: invalid color: %s", path, lineno, value);
return false;
}
*color = res & 0xffffff;
return true;
}
static bool static bool
parse_config_file(FILE *f, struct config *conf, const char *path) parse_config_file(FILE *f, struct config *conf, const char *path)
{ {
enum section { enum section {
SECTION_MAIN, SECTION_MAIN,
SECTION_COLORS,
} section = SECTION_MAIN; } section = SECTION_MAIN;
/* Function pointer, called for each key/value line */ /* Function pointer, called for each key/value line */
@ -123,11 +197,13 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
/* Maps sections to line parser functions */ /* Maps sections to line parser functions */
static const parser_fun_t section_parser_map[] = { static const parser_fun_t section_parser_map[] = {
[SECTION_MAIN] = &parse_section_main, [SECTION_MAIN] = &parse_section_main,
[SECTION_COLORS] = &parse_section_colors,
}; };
#if defined(_DEBUG) && defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG #if defined(_DEBUG) && defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG
static const char *const section_names[] = { static const char *const section_names[] = {
[SECTION_MAIN] = "main", [SECTION_MAIN] = "main",
[SECTION_COLORS] = "colors",
}; };
#endif #endif
@ -150,10 +226,25 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
break; break;
} }
/* No sections yet */ if (line[0] == '[') {
if (line[0] == '[' && line[strlen(line) - 1] == ']') { char *end = strchr(line, ']');
assert(false); if (end == NULL) {
return false; LOG_ERR("%s:%d: syntax error: %s", path, lineno, line);
free(line);
return false;
}
*end = '\0';
if (strcmp(&line[1], "colors") == 0)
section = SECTION_COLORS;
else {
LOG_ERR("%s:%d: invalid section name: %s", path, lineno, &line[1]);
free(line);
return false;
}
continue;
} }
char *key = strtok(line, "="); char *key = strtok(line, "=");
@ -219,6 +310,31 @@ config_load(struct config *conf)
.term = strdup("foot"), .term = strdup("foot"),
.shell = get_shell(), .shell = get_shell(),
.font = strdup("monospace"), .font = strdup("monospace"),
.colors = {
.fg = default_foreground,
.bg = default_background,
.regular = {
default_regular[0],
default_regular[1],
default_regular[2],
default_regular[3],
default_regular[4],
default_regular[5],
default_regular[6],
default_regular[7],
},
.bright = {
default_bright[0],
default_bright[1],
default_bright[2],
default_bright[3],
default_bright[4],
default_bright[5],
default_bright[6],
default_bright[7],
},
},
}; };
char *path = get_config_path(); char *path = get_config_path();

View file

@ -1,11 +1,19 @@
#pragma once #pragma once
#include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
struct config { struct config {
char *term; char *term;
char *shell; char *shell;
char *font; char *font;
struct {
uint32_t fg;
uint32_t bg;
uint32_t regular[8];
uint32_t bright[8];
} colors;
}; };
bool config_load(struct config *conf); bool config_load(struct config *conf);

101
csi.c
View file

@ -18,101 +18,37 @@
#define min(x, y) ((x) < (y) ? (x) : (y)) #define min(x, y) ((x) < (y) ? (x) : (y))
#if 0
static const struct rgb colors_regular[] = {
{0.000000, 0.000000, 0.000000}, /* 0x000000 */
{0.800000, 0.576471, 0.576471}, /* 0xcc9393 */
{0.498039, 0.623529, 0.498039}, /* 0x7f9f7f */
{0.815686, 0.749020, 0.560784}, /* 0xd0bf8f */
{0.423529, 0.627451, 0.639216}, /* 0x6ca0a3 */
{0.862745, 0.549020, 0.764706}, /* 0xdc8cc3 */
{0.576471, 0.878431, 0.890196}, /* 0x93e0e3 */
{0.862745, 0.862745, 0.800000}, /* 0xdcdccc */
};
static const struct rgb colors_bright[] = {
{0.000000, 0.000000, 0.000000}, /* 0x000000 */
{0.862745, 0.639216, 0.639216}, /* 0xdca3a3 */
{0.749020, 0.921569, 0.749020}, /* 0xbfebbf */
{0.941176, 0.874510, 0.686275}, /* 0xf0dfaf */
{0.549020, 0.815686, 0.827451}, /* 0x8cd0d3 */
{0.862745, 0.549020, 0.764706}, /* 0xdc8cc3 */
{0.576471, 0.878431, 0.890196}, /* 0x93e0e3 */
{1.000000, 1.000000, 1.000000}, /* 0xffffff */
};
static struct rgb colors256[256];
#else
static const uint32_t colors_regular[] = {
0x000000,
0xcc9393,
0x7f9f7f,
0xd0bf8f,
0x6ca0a3,
0xdc8cc3,
0x93e0e3,
0xdcdccc,
};
static const uint32_t colors_bright[] = {
0x000000,
0xdca3a3,
0xbfebbf,
0xf0dfaf,
0x8cd0d3,
0xdc8cc3,
0x93e0e3,
0xffffff,
};
static uint32_t colors256[256]; static uint32_t colors256[256];
#endif
static void __attribute__((constructor)) static void __attribute__((constructor))
initialize_colors256(void) initialize_colors256(void)
{ {
#if 0 /* pick colors from term struct instead, since they can be changed runtime */
for (size_t i = 0; i < 8; i++) for (size_t i = 0; i < 8; i++)
colors256[i] = colors_regular[i]; colors256[i] = colors_regular[i];
for (size_t i = 0; i < 8; i++) for (size_t i = 0; i < 8; i++)
colors256[8 + i] = colors_bright[i]; colors256[8 + i] = colors_bright[i];
#endif
for (size_t r = 0; r < 6; r++) { for (size_t r = 0; r < 6; r++) {
for (size_t g = 0; g < 6; g++) { for (size_t g = 0; g < 6; g++) {
for (size_t b = 0; b < 6; b++) { for (size_t b = 0; b < 6; b++) {
#if 0
colors256[16 + r * 6 * 6 + g * 6 + b] = (struct rgb) {
r * 51 / 255.0,
g * 51 / 255.0,
b * 51 / 255.0,
};
#else
colors256[16 + r * 6 * 6 + g * 6 + b] colors256[16 + r * 6 * 6 + g * 6 + b]
= r * 51 << 16 | g * 51 << 8 | b * 51; = r * 51 << 16 | g * 51 << 8 | b * 51;
#endif
} }
} }
} }
for (size_t i = 0; i < 24; i++){ for (size_t i = 0; i < 24; i++)
#if 0
colors256[232 + i] = (struct rgb) {
i * 11 / 255.0,
i * 11 / 255.0,
i * 11 / 255.0,
};
#else
/* TODO: i + 1? */
colors256[232 + i] = i * 11 << 16 | i * 11 << 8 | i * 11; colors256[232 + i] = i * 11 << 16 | i * 11 << 8 | i * 11;
#endif
}
} }
static void static void
sgr_reset(struct terminal *term) sgr_reset(struct terminal *term)
{ {
memset(&term->vt.attrs, 0, sizeof(term->vt.attrs)); memset(&term->vt.attrs, 0, sizeof(term->vt.attrs));
term->vt.attrs.foreground = term->foreground; term->vt.attrs.foreground = term->colors.fg;
term->vt.attrs.background = term->background; term->vt.attrs.background = term->colors.bg;
} }
static const char * static const char *
@ -190,7 +126,7 @@ csi_sgr(struct terminal *term)
case 35: case 35:
case 36: case 36:
case 37: case 37:
term->vt.attrs.foreground = 1 << 31 | colors_regular[param - 30]; term->vt.attrs.foreground = 1 << 31 | term->colors.regular[param - 30];
break; break;
case 38: { case 38: {
@ -198,7 +134,14 @@ csi_sgr(struct terminal *term)
term->vt.params.v[i + 1].value == 5) term->vt.params.v[i + 1].value == 5)
{ {
uint8_t idx = term->vt.params.v[i + 2].value; uint8_t idx = term->vt.params.v[i + 2].value;
term->vt.attrs.foreground = 1 << 31 | colors256[idx]; uint32_t color;
if (idx < 8)
color = term->colors.regular[idx];
else if (idx < 16)
color = term->colors.bright[idx - 8];
else
color = colors256[idx];
term->vt.attrs.foreground = 1 << 31 | color;
i += 2; i += 2;
} }
@ -252,7 +195,7 @@ csi_sgr(struct terminal *term)
case 45: case 45:
case 46: case 46:
case 47: case 47:
term->vt.attrs.background = 1 << 31 | colors_regular[param - 40]; term->vt.attrs.background = 1 << 31 | term->colors.regular[param - 40];
break; break;
case 48: { case 48: {
@ -260,7 +203,15 @@ csi_sgr(struct terminal *term)
term->vt.params.v[i + 1].value == 5) term->vt.params.v[i + 1].value == 5)
{ {
uint8_t idx = term->vt.params.v[i + 2].value; uint8_t idx = term->vt.params.v[i + 2].value;
term->vt.attrs.background = 1 << 31 | colors256[idx]; uint32_t color;
if (idx < 8)
color = term->colors.regular[idx];
else if (idx < 16)
color = term->colors.bright[idx - 8];
else
color = colors256[idx];
term->vt.attrs.background = 1 << 31 | color;
i += 2; i += 2;
} }
@ -314,7 +265,7 @@ csi_sgr(struct terminal *term)
case 95: case 95:
case 96: case 96:
case 97: case 97:
term->vt.attrs.foreground = 1 << 31 | colors_bright[param - 90]; term->vt.attrs.foreground = 1 << 31 | term->colors.bright[param - 90];
break; break;
/* Regular background colors */ /* Regular background colors */
@ -326,7 +277,7 @@ csi_sgr(struct terminal *term)
case 105: case 105:
case 106: case 106:
case 107: case 107:
term->vt.attrs.background = 1 << 31 | colors_bright[param - 100]; term->vt.attrs.background = 1 << 31 | term->colors.bright[param - 100];
break; break;
default: default:

46
main.c
View file

@ -36,14 +36,6 @@
#define min(x, y) ((x) < (y) ? (x) : (y)) #define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y))
#if 0
static const struct rgb default_foreground = {0.86, 0.86, 0.86};
static const struct rgb default_background = {0.067, 0.067, 0.067};
#else
static const uint32_t default_foreground = 0xdcdccc;
static const uint32_t default_background = 0x111111;
#endif
static void static void
shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
{ {
@ -335,8 +327,8 @@ main(int argc, char *const *argv)
.vt = { .vt = {
.state = 1, /* STATE_GROUND */ .state = 1, /* STATE_GROUND */
.attrs = { .attrs = {
.foreground = default_foreground, //.foreground = conf.colors.fg,
.background = default_background, //.background = conf.colors.bg
}, },
}, },
.kbd = { .kbd = {
@ -346,8 +338,30 @@ main(int argc, char *const *argv)
.cmd = REPEAT_STOP, .cmd = REPEAT_STOP,
}, },
}, },
.foreground = default_foreground, .colors = {
.background = default_background, .default_fg = conf.colors.fg,
.default_bg = conf.colors.bg,
.default_regular = {
conf.colors.regular[0],
conf.colors.regular[1],
conf.colors.regular[2],
conf.colors.regular[3],
conf.colors.regular[4],
conf.colors.regular[5],
conf.colors.regular[6],
conf.colors.regular[7],
},
.default_bright = {
conf.colors.bright[0],
conf.colors.bright[1],
conf.colors.bright[2],
conf.colors.bright[3],
conf.colors.bright[4],
conf.colors.bright[5],
conf.colors.bright[6],
conf.colors.bright[7],
},
},
.selection = { .selection = {
.start = {-1, -1}, .start = {-1, -1},
.end = {-1, -1}, .end = {-1, -1},
@ -357,6 +371,14 @@ main(int argc, char *const *argv)
.grid = &term.normal, .grid = &term.normal,
}; };
/* Initialize 'current' colors from the default colors */
term.colors.fg = term.colors.default_fg;
term.colors.bg = term.colors.default_bg;
for (size_t i = 0; i < 8; i++) {
term.colors.regular[i] = term.colors.default_regular[i];
term.colors.bright[i] = term.colors.default_bright[i];
}
if (term.ptmx == -1) { if (term.ptmx == -1) {
LOG_ERRNO("failed to open pseudo terminal"); LOG_ERRNO("failed to open pseudo terminal");
goto out; goto out;

2
osc.c
View file

@ -18,7 +18,7 @@ osc_query(struct terminal *term, unsigned param)
switch (param) { switch (param) {
case 10: case 10:
case 11: { case 11: {
uint32_t color = param == 10 ? term->foreground : term->background; uint32_t color = param == 10 ? term->colors.fg : term->colors.bg;
uint8_t r = (color >> 16) & 0xff; uint8_t r = (color >> 16) & 0xff;
uint8_t g = (color >> 8) & 0xff; uint8_t g = (color >> 8) & 0xff;
uint8_t b = (color >> 0) & 0xff; uint8_t b = (color >> 0) & 0xff;

View file

@ -105,10 +105,10 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
uint32_t _fg = cell->attrs.foreground >> 31 uint32_t _fg = cell->attrs.foreground >> 31
? cell->attrs.foreground ? cell->attrs.foreground
: !term->reverse ? term->foreground : term->background; : !term->reverse ? term->colors.fg : term->colors.bg;
uint32_t _bg = cell->attrs.background >> 31 uint32_t _bg = cell->attrs.background >> 31
? cell->attrs.background ? cell->attrs.background
: !term->reverse ? term->background : term->foreground; : !term->reverse ? term->colors.bg : term->colors.fg;
/* If *one* is set, we reverse */ /* If *one* is set, we reverse */
if (has_cursor ^ cell->attrs.reverse ^ is_selected) { if (has_cursor ^ cell->attrs.reverse ^ is_selected) {
@ -307,7 +307,7 @@ grid_render(struct terminal *term)
int rmargin_width = term->width - rmargin; int rmargin_width = term->width - rmargin;
int bmargin_height = term->height - bmargin; int bmargin_height = term->height - bmargin;
uint32_t _bg = !term->reverse ? term->background : term->foreground; uint32_t _bg = !term->reverse ? term->colors.bg : term->colors.fg;
struct rgb bg = color_hex_to_rgb(_bg); struct rgb bg = color_hex_to_rgb(_bg);
cairo_set_source_rgb(buf->cairo, bg.r, bg.g, bg.b); cairo_set_source_rgb(buf->cairo, bg.r, bg.g, bg.b);

View file

@ -259,8 +259,17 @@ struct terminal {
bool print_needs_wrap; bool print_needs_wrap;
struct scroll_region scroll_region; struct scroll_region scroll_region;
uint32_t foreground; struct {
uint32_t background; uint32_t fg;
uint32_t bg;
uint32_t regular[8];
uint32_t bright[8];
uint32_t default_fg;
uint32_t default_bg;
uint32_t default_regular[8];
uint32_t default_bright[8];
} colors;
struct { struct {
int col; int col;