From 8e37a18083e8cdba1cfd4ee042d8f8edf7cfad39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 22 Feb 2020 14:02:00 +0100 Subject: [PATCH] sixel: application configurable palette size (color count) This implements the CSI escapes for retrieving and (re)setting the palette size. --- csi.c | 25 +++++++++++++++++++++++++ sixel.c | 41 +++++++++++++++++++++++++++++++++++------ sixel.h | 7 +++++++ terminal.c | 3 +++ terminal.h | 3 +++ 5 files changed, 73 insertions(+), 6 deletions(-) diff --git a/csi.c b/csi.c index ed237592..d5c06905 100644 --- a/csi.c +++ b/csi.c @@ -15,6 +15,7 @@ #include "grid.h" #include "vt.h" #include "selection.h" +#include "sixel.h" #define min(x, y) ((x) < (y) ? (x) : (y)) @@ -1227,6 +1228,30 @@ csi_dispatch(struct terminal *term, uint8_t final) } break; + case 'S': { + unsigned target = vt_param_get(term, 0, 0); + unsigned operation = vt_param_get(term, 1, 0); + + switch (target) { + case 1: + switch (operation) { + case 1: sixel_colors_report_current(term); break; + case 2: sixel_colors_reset(term); break; + case 3: sixel_colors_set(term, vt_param_get(term, 2, 0)); break; + case 4: sixel_colors_report_max(term); + } + break; + + case 2: + break; + + case 3: + break; + + } + break; + } + default: UNHANDLED(); break; diff --git a/sixel.c b/sixel.c index 69025669..2536f467 100644 --- a/sixel.c +++ b/sixel.c @@ -11,7 +11,6 @@ #define max(x, y) ((x) > (y) ? (x) : (y)) #define min(x, y) ((x) < (y) ? (x) : (y)) -static const size_t COLOR_COUNT = 1024; static size_t count; @@ -20,6 +19,7 @@ sixel_init(struct terminal *term) { assert(term->sixel.palette == NULL); assert(term->sixel.image.data == NULL); + assert(term->sixel.palette_size <= SIXEL_MAX_COLORS); term->sixel.state = SIXEL_DECSIXEL; term->sixel.pos = (struct coord){0, 0}; @@ -28,7 +28,7 @@ sixel_init(struct terminal *term) term->sixel.param = 0; term->sixel.param_idx = 0; memset(term->sixel.params, 0, sizeof(term->sixel.params)); - term->sixel.palette = calloc(COLOR_COUNT, sizeof(term->sixel.palette[0])); + term->sixel.palette = calloc(term->sixel.palette_size, sizeof(term->sixel.palette[0])); term->sixel.image.data = malloc(1 * 6 * sizeof(term->sixel.image.data[0])); term->sixel.image.width = 1; term->sixel.image.height = 6; @@ -309,10 +309,8 @@ decgci(struct terminal *term, uint8_t c) int nparams = term->sixel.param_idx; - if (nparams > 0) { - /* Add one, as we use idx==0 for background color (TODO) */ - term->sixel.color_idx = min(1 + term->sixel.params[0], COLOR_COUNT - 1); - } + if (nparams > 0) + term->sixel.color_idx = min(term->sixel.params[0], term->sixel.palette_size - 1); if (nparams > 4) { unsigned format = term->sixel.params[1]; @@ -360,3 +358,34 @@ sixel_put(struct terminal *term, uint8_t c) count++; } + +void +sixel_colors_report_current(struct terminal *term) +{ + char reply[24]; + snprintf(reply, sizeof(reply), "\033[?1;0;%uS", term->sixel.palette_size); + term_to_slave(term, reply, strlen(reply)); +} + +void +sixel_colors_reset(struct terminal *term) +{ + term->sixel.palette_size = SIXEL_MAX_COLORS; + LOG_DBG("sixel palette size reset to %u", SIXEL_MAX_COLORS); +} + +void +sixel_colors_set(struct terminal *term, unsigned count) +{ + unsigned new_palette_size = min(max(2, count), SIXEL_MAX_COLORS); + term->sixel.palette_size = new_palette_size; + LOG_DBG("sixel palette size set to %u", new_palette_size); +} + +void +sixel_colors_report_max(struct terminal *term) +{ + char reply[24]; + snprintf(reply, sizeof(reply), "\033[?1;0;%uS", SIXEL_MAX_COLORS); + term_to_slave(term, reply, strlen(reply)); +} diff --git a/sixel.h b/sixel.h index 5933cf81..8e6d2949 100644 --- a/sixel.h +++ b/sixel.h @@ -2,8 +2,15 @@ #include "terminal.h" +#define SIXEL_MAX_COLORS 1024u + void sixel_init(struct terminal *term); void sixel_put(struct terminal *term, uint8_t c); void sixel_unhook(struct terminal *term); void sixel_destroy(struct sixel *sixel); + +void sixel_colors_report_current(struct terminal *term); +void sixel_colors_reset(struct terminal *term); +void sixel_colors_set(struct terminal *term, unsigned count); +void sixel_colors_report_max(struct terminal *term); diff --git a/terminal.c b/terminal.c index 3350c065..493a8ada 100644 --- a/terminal.c +++ b/terminal.c @@ -741,6 +741,9 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, .lower_fd = delay_lower_fd, .upper_fd = delay_upper_fd, }, + .sixel = { + .palette_size = SIXEL_MAX_COLORS, + }, .sixel_images = tll_init(), .hold_at_exit = conf->hold_at_exit, .shutdown_cb = shutdown_cb, diff --git a/terminal.h b/terminal.h index 882abfba..e0738057 100644 --- a/terminal.h +++ b/terminal.h @@ -376,6 +376,9 @@ struct terminal { unsigned params[5]; /* Collected parmaeters, for RASTER, COLOR_SPEC */ unsigned param; /* Currently collecting parameter, for RASTER, COLOR_SPEC and REPEAT */ unsigned param_idx; /* Parameters seen */ + + /* Application configurable */ + unsigned palette_size; } sixel; tll(struct sixel) sixel_images;