From 2245782dd45728619b8ba024aaf3055e6e0cc1db Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Thu, 2 Jul 2020 22:25:43 +0200 Subject: [PATCH] termptyesc: handle xterm color format starting with "rgb:" --- src/bin/termptyesc.c | 107 ++++++++++++++++++++++++++++++++++++++ tests/tests.results | 1 + tests/xterm-colors-rgb.sh | 80 ++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100755 tests/xterm-colors-rgb.sh diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c index 932b782a..f4f79408 100644 --- a/src/bin/termptyesc.c +++ b/src/bin/termptyesc.c @@ -3762,6 +3762,98 @@ _xterm_parse_color_sharp(Eina_Unicode *p, return 0; } +static int +_xterm_parse_color_rgbi(Eina_Unicode *p EINA_UNUSED, + unsigned char *r EINA_UNUSED, + unsigned char *g EINA_UNUSED, + unsigned char *b EINA_UNUSED, + int len EINA_UNUSED) +{ + return -1; +} + +/* returns len read or -1 in case of error */ +static int +_xterm_parse_hex(Eina_Unicode *p, unsigned char *c, int len) +{ + int l = 0; + int v = 0; + int i; + + i = _eina_unicode_to_hex(p[0]); + if (i < 0) return -1; + p++; + l++; + len--; + if (len <= 0) + goto end; + v = i; + + i = _eina_unicode_to_hex(p[0]); + if (i < 0) goto end; + p++; + l++; + len--; + if (len <= 0) + goto end; + v = v * 16 + i; + + i = _eina_unicode_to_hex(p[0]); + if (i < 0) goto end; + p++; + l++; + len--; + if (len <= 0) + goto end; + + i = _eina_unicode_to_hex(p[0]); + if (i < 0) goto end; + p++; + l++; + len--; + if (len <= 0) + goto end; + +end: + if (l == 1) + v <<= 4; + *c = v; + if (l > 0) + return l; + return -1; +} + +static int +_xterm_parse_color_rgb(Eina_Unicode *p, + unsigned char *r, unsigned char *g, unsigned char *b, + int len) +{ + int l; + + /* parse r */ + l = _xterm_parse_hex(p, r, len); + if (l <= 0) + return -1; + p += l; + if (p[0] != '/') + return -1; + p++; + /* parse g */ + l = _xterm_parse_hex(p, g, len); + if (l <= 0) + return -1; + p += l; + if (p[0] != '/') + return -1; + p++; + /* parse b */ + l = _xterm_parse_hex(p, b, len); + if (l <= 0) + return -1; + + return 0; +} + static int _xterm_parse_color(Termpty *ty, Eina_Unicode **ptr, @@ -3777,6 +3869,21 @@ _xterm_parse_color(Termpty *ty, Eina_Unicode **ptr, if (_xterm_parse_color_sharp(p, r, g, b, len)) goto err; } + else if (len > 5 && p[0] == 'r' && p[1] == 'g' && p[2] == 'b') + { + if (p[3] == 'i' && p[4] == ':') + { + if (_xterm_parse_color_rgbi(p+5, r, g, b, len-5)) + goto err; + } + else if (p[3] == ':') + { + if (_xterm_parse_color_rgb(p+4, r, g, b, len-4)) + goto err; + } + else + goto err; + } else goto err; diff --git a/tests/tests.results b/tests/tests.results index 369da827..1d33d208 100644 --- a/tests/tests.results +++ b/tests/tests.results @@ -146,3 +146,4 @@ crash_empty_osc.sh b87272896ce7be9856253b32be1bef14 xterm-osc-10.sh b8c23c9c5482b1e9c30d8a261edc29f0 xterm-osc-11.sh 3e02038964b78d948fb599c996bf370d xterm-colors-sharp.sh 79d6f72df04237d76a0fa3e722dcec5b +xterm-colors-rgb.sh d9b55817ef8428343105b44dabd535a8 diff --git a/tests/xterm-colors-rgb.sh b/tests/xterm-colors-rgb.sh new file mode 100755 index 00000000..06ee96d9 --- /dev/null +++ b/tests/xterm-colors-rgb.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# char width: 7 +# char height: 15 + +# set color +printf '\033[0;31;3m' + +# clear screen +printf '\033[2J' + +# move to 0; 0 +printf '\033[0;0H' + +# set color +printf '\033[0m' + +printf 'The purpose of computing is insight, not numbers.\r\n' +printf 'Richard Hamming\r\n' + +# valid colors +# one nibble per color +printf '\033]10;rgb:f/0/f\007' +# two nibble per color +printf '\033]10;rgb:ff/00/ff\007' +# three nibble per color +printf '\033]10;rgb:fff/000/fff\007' +# four nibble per color +printf '\033]10;rgb:FFFF/0000/FFFF\007' + +## +# invalid +## + +# not hex +# one nibble per color +printf '\033]10;rgb:g/0/f\007' +printf '\033]10;rgb:f/g/f\007' +printf '\033]10;rgb:f/0/g\007' +# two nibble per color +printf '\033]10;rgb:gf/00/ff\007' +printf '\033]10;rgb:fg/00/ff\007' +printf '\033]10;rgb:ff/g0/ff\007' +printf '\033]10;rgb:ff/0g/ff\007' +printf '\033]10;rgb:ff/00/gf\007' +printf '\033]10;rgb:ff/00/fg\007' +# three nibble per color +printf '\033]10;rgb:gff/000/fff\007' +printf '\033]10;rgb:fgf/000/fff\007' +printf '\033]10;rgb:ffg/000/fff\007' +printf '\033]10;rgb:fff/g00/fff\007' +printf '\033]10;rgb:fff/0g0/fff\007' +printf '\033]10;rgb:fff/00g/fff\007' +printf '\033]10;rgb:fff/000/gff\007' +printf '\033]10;rgb:fff/000/fgf\007' +printf '\033]10;rgb:fff/000/ffg\007' +# four nibble per color +printf '\033]10;rgb:gFFF/0000/FFFF\007' +printf '\033]10;rgb:FgFF/0000/FFFF\007' +printf '\033]10;rgb:FFgF/0000/FFFF\007' +printf '\033]10;rgb:FFFg/0000/FFFF\007' +printf '\033]10;rgb:FFFF/g000/FFFF\007' +printf '\033]10;rgb:FFFF/0g00/FFFF\007' +printf '\033]10;rgb:FFFF/00g0/FFFF\007' +printf '\033]10;rgb:FFFF/000g/FFFF\007' +printf '\033]10;rgb:FFFF/0000/gFFF\007' +printf '\033]10;rgb:FFFF/0000/FgFF\007' +printf '\033]10;rgb:FFFF/0000/FFgF\007' +printf '\033]10;rgb:FFFF/0000/FFFg\007' + +# too short +printf '\033]10;rgb:/F/F\007' +printf '\033]10;rgb:F//F\007' +printf '\033]10;rgb:F/F/\007' +# too long +printf '\033]10;rgb:FFFFF/0000/FFFF\007' +printf '\033]10;rgb:FFFF/00000/FFFF\007' +printf '\033]10;rgb:FFFF/0000/FFFFF\007' +printf '\033]10;rgb:FFFF/0000/FFFF/\007' +printf '\033]10;rgb:FFFF/0000/FFFF/0000\007'