Compare commits
1 commit
master
...
support/vt
Author | SHA1 | Date | |
---|---|---|---|
|
cd3a9612e3 |
8 changed files with 10 additions and 1029 deletions
586
ctrlseq/dcs.h
586
ctrlseq/dcs.h
|
@ -1,586 +0,0 @@
|
|||
/* See LICENSE for licence details. */
|
||||
/* function for dcs sequence */
|
||||
enum {
|
||||
RGBMAX = 255,
|
||||
HUEMAX = 360,
|
||||
LSMAX = 100,
|
||||
};
|
||||
|
||||
/*
|
||||
static inline void split_rgb(uint32_t color, uint8_t *r, uint8_t *g, uint8_t *b)
|
||||
{
|
||||
*r = bit_mask[8] & (color >> 16);
|
||||
*g = bit_mask[8] & (color >> 8);
|
||||
*b = bit_mask[8] & (color >> 0);
|
||||
}
|
||||
*/
|
||||
|
||||
static inline int sixel_bitmap(struct terminal_t *term, struct sixel_canvas_t *sc, uint8_t bitmap)
|
||||
{
|
||||
int i, offset;
|
||||
//uint8_t r, g, b;
|
||||
|
||||
logging(DEBUG, "sixel_bitmap()\nbitmap:%.2X point(%d, %d)\n",
|
||||
bitmap, sc->point.x, sc->point.y);
|
||||
|
||||
if (sc->point.x >= term->width || sc->point.y >= term->height)
|
||||
return 1;
|
||||
|
||||
offset = sc->point.x * BYTES_PER_PIXEL + sc->point.y * sc->line_length;
|
||||
|
||||
for (i = 0; i < BITS_PER_SIXEL; i++) {
|
||||
if (offset >= BYTES_PER_PIXEL * term->width * term->height)
|
||||
break;
|
||||
|
||||
if (bitmap & (0x01 << i)) {
|
||||
memcpy(sc->pixmap + offset, &sc->color_table[sc->color_index], BYTES_PER_PIXEL);
|
||||
/*
|
||||
split_rgb(sc->color_table[sc->color_index], &r, &g, &b);
|
||||
*(sc->pixmap + offset + 0) = b;
|
||||
*(sc->pixmap + offset + 1) = g;
|
||||
*(sc->pixmap + offset + 2) = r;
|
||||
*/
|
||||
}
|
||||
|
||||
offset += sc->line_length;
|
||||
}
|
||||
sc->point.x++;
|
||||
|
||||
if (sc->point.x > sc->width)
|
||||
sc->width = sc->point.x;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int sixel_repeat(struct terminal_t *term, struct sixel_canvas_t *sc, char *buf)
|
||||
{
|
||||
int i, count;
|
||||
size_t length;
|
||||
char *cp, tmp[BUFSIZE];
|
||||
uint8_t bitmap;
|
||||
|
||||
cp = buf + 1; /* skip '!' itself */
|
||||
while (isdigit(*cp)) /* skip non sixel bitmap character */
|
||||
cp++;
|
||||
|
||||
length = (cp - buf);
|
||||
strncpy(tmp, buf + 1, length - 1);
|
||||
*(tmp + length - 1) = '\0';
|
||||
|
||||
count = dec2num(tmp);
|
||||
|
||||
logging(DEBUG, "sixel_repeat()\nbuf:%s length:%u\ncount:%d repeat:0x%.2X\n",
|
||||
tmp, (unsigned) length, count, *cp);
|
||||
|
||||
if ('?' <= *cp && *cp <= '~') {
|
||||
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
||||
for (i = 0; i < count; i++)
|
||||
sixel_bitmap(term, sc, bitmap);
|
||||
}
|
||||
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
static inline int sixel_attr(struct sixel_canvas_t *sc, char *buf)
|
||||
{
|
||||
char *cp, tmp[BUFSIZE];
|
||||
size_t length;
|
||||
struct parm_t parm;
|
||||
|
||||
cp = buf + 1;
|
||||
while (isdigit(*cp) || *cp == ';') /* skip valid params */
|
||||
cp++;
|
||||
|
||||
length = (cp - buf);
|
||||
strncpy(tmp, buf + 1, length - 1);
|
||||
*(tmp + length - 1) = '\0';
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(tmp, &parm, ';', isdigit);
|
||||
|
||||
if (parm.argc >= 4) {
|
||||
sc->width = dec2num(parm.argv[2]);
|
||||
sc->height = dec2num(parm.argv[3]);
|
||||
}
|
||||
|
||||
logging(DEBUG, "sixel_attr()\nbuf:%s\nwidth:%d height:%d\n",
|
||||
tmp, sc->width, sc->height);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static inline uint32_t hue2rgb(int n1, int n2, int hue)
|
||||
{
|
||||
if (hue < 0)
|
||||
hue += HUEMAX;
|
||||
|
||||
if (hue > HUEMAX)
|
||||
hue -= HUEMAX;
|
||||
|
||||
if (hue < (HUEMAX / 6))
|
||||
return (n1 + (((n2 - n1) * hue + (HUEMAX / 12)) / (HUEMAX / 6)));
|
||||
if (hue < (HUEMAX / 2))
|
||||
return n2;
|
||||
if (hue < ((HUEMAX * 2) / 3))
|
||||
return (n1 + (((n2 - n1) * (((HUEMAX * 2) / 3) - hue) + (HUEMAX / 12)) / (HUEMAX / 6)));
|
||||
else
|
||||
return n1;
|
||||
}
|
||||
|
||||
static inline uint32_t hls2rgb(int hue, int lum, int sat)
|
||||
{
|
||||
uint32_t r, g, b;
|
||||
int magic1, magic2;
|
||||
|
||||
if (sat == 0) {
|
||||
r = g = b = (lum * RGBMAX) / LSMAX;
|
||||
} else {
|
||||
if (lum <= (LSMAX / 2) )
|
||||
magic2 = (lum * (LSMAX + sat) + (LSMAX / 2)) / LSMAX;
|
||||
else
|
||||
magic2 = lum + sat - ((lum * sat) + (LSMAX / 2)) / LSMAX;
|
||||
magic1 = 2 * lum - magic2;
|
||||
|
||||
r = (hue2rgb(magic1, magic2, hue + (HUEMAX / 3)) * RGBMAX + (LSMAX / 2)) / LSMAX;
|
||||
g = (hue2rgb(magic1, magic2, hue) * RGBMAX + (LSMAX / 2)) / LSMAX;
|
||||
b = (hue2rgb(magic1, magic2, hue - (HUEMAX / 3)) * RGBMAX + (LSMAX/2)) / LSMAX;
|
||||
}
|
||||
return (r << 16) + (g << 8) + b;
|
||||
}
|
||||
|
||||
static inline int sixel_color(struct sixel_canvas_t *sc, char *buf)
|
||||
{
|
||||
char *cp, tmp[BUFSIZE];
|
||||
int index, type;
|
||||
size_t length;
|
||||
uint16_t v1, v2, v3, r, g, b;
|
||||
uint32_t color;
|
||||
struct parm_t parm;
|
||||
|
||||
cp = buf + 1;
|
||||
while (isdigit(*cp) || *cp == ';') /* skip valid params */
|
||||
cp++;
|
||||
|
||||
length = (cp - buf);
|
||||
strncpy(tmp, buf + 1, length - 1); /* skip '#' */
|
||||
*(tmp + length - 1) = '\0';
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(tmp, &parm, ';', isdigit);
|
||||
|
||||
if (parm.argc < 1)
|
||||
return length;
|
||||
|
||||
index = dec2num(parm.argv[0]);
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
else if (index >= COLORS)
|
||||
index = COLORS - 1;
|
||||
|
||||
logging(DEBUG, "sixel_color()\nbuf:%s length:%u\nindex:%d\n",
|
||||
tmp, (unsigned) length, index);
|
||||
|
||||
if (parm.argc == 1) { /* select color */
|
||||
sc->color_index = index;
|
||||
return length;
|
||||
}
|
||||
|
||||
if (parm.argc != 5)
|
||||
return length;
|
||||
|
||||
type = dec2num(parm.argv[1]);
|
||||
v1 = dec2num(parm.argv[2]);
|
||||
v2 = dec2num(parm.argv[3]);
|
||||
v3 = dec2num(parm.argv[4]);
|
||||
|
||||
if (type == 1) { /* HLS */
|
||||
color = hls2rgb(v1, v2, v3);
|
||||
} else {
|
||||
r = bit_mask[8] & (0xFF * v1 / 100);
|
||||
g = bit_mask[8] & (0xFF * v2 / 100);
|
||||
b = bit_mask[8] & (0xFF * v3 / 100);
|
||||
color = (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
logging(DEBUG, "type:%d v1:%u v2:%u v3:%u color:0x%.8X\n",
|
||||
type, v1, v2, v3, color);
|
||||
|
||||
sc->color_table[index] = color;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static inline int sixel_cr(struct sixel_canvas_t *sc)
|
||||
{
|
||||
logging(DEBUG, "sixel_cr()\n");
|
||||
|
||||
sc->point.x = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int sixel_nl(struct sixel_canvas_t *sc)
|
||||
{
|
||||
logging(DEBUG, "sixel_nl()\n");
|
||||
|
||||
/* DECGNL moves active position to left margin
|
||||
and down one line of sixels:
|
||||
http://odl.sysworks.biz/disk$vaxdocdec963/decw$book/d3qsaaa1.p67.decw$book */
|
||||
sc->point.y += BITS_PER_SIXEL;
|
||||
sc->point.x = 0;
|
||||
|
||||
if (sc->point.y > sc->height)
|
||||
sc->height = sc->point.y;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sixel_parse_data(struct terminal_t *term, struct sixel_canvas_t *sc, char *start_buf)
|
||||
{
|
||||
/*
|
||||
DECDLD sixel data
|
||||
'$': carriage return
|
||||
'-': new line
|
||||
'#': color
|
||||
# Pc: select color
|
||||
# Pc; Pu; Px; Py; Pz
|
||||
Pc : color index (0 to 255)
|
||||
Pu : color coordinate system
|
||||
1: HLS (0 to 360 for Hue, 0 to 100 for others)
|
||||
2: RGB (0 to 100 percent) (default)
|
||||
Px : Hue / Red
|
||||
Py : Lightness / Green
|
||||
Pz : Saturation / Blue
|
||||
'"': attr
|
||||
" Pan; Pad; Ph; Pv
|
||||
Pan, Pad: defines aspect ratio (Pan / Pad) (ignored)
|
||||
Ph, Pv : defines vertical/horizontal size of the image
|
||||
'!': repeat
|
||||
! Pn ch
|
||||
Pn : repeat count ([0-9]+)
|
||||
ch : character to repeat ('?' to '~')
|
||||
sixel bitmap:
|
||||
range of ? (hex 3F) to ~ (hex 7E)
|
||||
? (hex 3F) represents the binary value 00 0000.
|
||||
t (hex 74) represents the binary value 11 0101.
|
||||
~ (hex 7E) represents the binary value 11 1111.
|
||||
*/
|
||||
int size = 0;
|
||||
char *cp, *end_buf;
|
||||
uint8_t bitmap;
|
||||
|
||||
cp = start_buf;
|
||||
end_buf = cp + strlen(start_buf);
|
||||
|
||||
while (cp < end_buf) {
|
||||
if (*cp == '!') {
|
||||
size = sixel_repeat(term, sc, cp);
|
||||
} else if (*cp == '"') {
|
||||
size = sixel_attr(sc, cp);
|
||||
} else if (*cp == '#') {
|
||||
size = sixel_color(sc, cp);
|
||||
} else if (*cp == '$') {
|
||||
size = sixel_cr(sc);
|
||||
} else if (*cp == '-') {
|
||||
size = sixel_nl(sc);
|
||||
} else if ('?' <= *cp && *cp <= '~') {
|
||||
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
||||
size = sixel_bitmap(term, sc, bitmap);
|
||||
} else if (*cp == '\0') { /* end of sixel data */
|
||||
break;
|
||||
} else {
|
||||
size = 1;
|
||||
}
|
||||
cp += size;
|
||||
}
|
||||
|
||||
logging(DEBUG, "sixel_parse_data()\nwidth:%d height:%d\n", sc->width, sc->height);
|
||||
}
|
||||
|
||||
void reset_sixel(struct sixel_canvas_t *sc, struct color_pair_t color_pair, int width, int height)
|
||||
{
|
||||
extern const uint32_t color_list[]; /* global */
|
||||
int i;
|
||||
|
||||
memset(sc->pixmap, 0, BYTES_PER_PIXEL * width * height);
|
||||
|
||||
sc->width = 1;
|
||||
sc->height = 6;
|
||||
sc->point.x = 0;
|
||||
sc->point.y = 0;
|
||||
sc->line_length = BYTES_PER_PIXEL * width;
|
||||
sc->color_index = 0;
|
||||
|
||||
/* 0 - 15: use vt340 or ansi color map */
|
||||
/* VT340 VT340 Default Color Map
|
||||
ref: http://www.vt100.net/docs/vt3xx-gp/chapter2.html#T2-3
|
||||
*/
|
||||
sc->color_table[0] = 0x000000; sc->color_table[8] = 0x424242;
|
||||
sc->color_table[1] = 0x3333CC; sc->color_table[9] = 0x545499;
|
||||
sc->color_table[2] = 0xCC2121; sc->color_table[10] = 0x994242;
|
||||
sc->color_table[3] = 0x33CC33; sc->color_table[11] = 0x549954;
|
||||
sc->color_table[4] = 0xCC33CC; sc->color_table[12] = 0x995499;
|
||||
sc->color_table[5] = 0x33CCCC; sc->color_table[13] = 0x549999;
|
||||
sc->color_table[6] = 0xCCCC33; sc->color_table[14] = 0x999954;
|
||||
sc->color_table[7] = 0x878787; sc->color_table[15] = 0xCCCCCC;
|
||||
|
||||
/* ANSI 16color table (but unusual order corresponding vt340 color map)
|
||||
sc->color_table[0] = color_list[0]; sc->color_table[8] = color_list[8];
|
||||
sc->color_table[1] = color_list[4]; sc->color_table[9] = color_list[12];
|
||||
sc->color_table[2] = color_list[1]; sc->color_table[10] = color_list[9];
|
||||
sc->color_table[3] = color_list[2]; sc->color_table[11] = color_list[10];
|
||||
sc->color_table[4] = color_list[5]; sc->color_table[12] = color_list[13];
|
||||
sc->color_table[5] = color_list[6]; sc->color_table[13] = color_list[14];
|
||||
sc->color_table[6] = color_list[3]; sc->color_table[14] = color_list[11];
|
||||
sc->color_table[7] = color_list[7]; sc->color_table[15] = color_list[15];
|
||||
*/
|
||||
/* change palette 0, because its often the same color as terminal background */
|
||||
sc->color_table[0] = color_list[color_pair.fg];
|
||||
|
||||
/* 16 - 255: use xterm 256 color palette */
|
||||
/* copy 256 color map */
|
||||
for (i = 16; i < COLORS; i++)
|
||||
sc->color_table[i] = color_list[i];
|
||||
}
|
||||
|
||||
void sixel_copy2cell(struct terminal_t *term, struct sixel_canvas_t *sc)
|
||||
{
|
||||
int y, x, h, cols, lines;
|
||||
int src_offset, dst_offset;
|
||||
struct cell_t *cellp;
|
||||
|
||||
if (sc->height > term->height)
|
||||
sc->height = term->height;
|
||||
|
||||
cols = my_ceil(sc->width, CELL_WIDTH);
|
||||
lines = my_ceil(sc->height, CELL_HEIGHT);
|
||||
|
||||
if (cols + term->cursor.x > term->cols)
|
||||
cols -= (cols + term->cursor.x - term->cols);
|
||||
|
||||
for (y = 0; y < lines; y++) {
|
||||
for (x = 0; x < cols; x++) {
|
||||
erase_cell(term, term->cursor.y, term->cursor.x + x);
|
||||
cellp = &term->cells[term->cursor.y][term->cursor.x + x];
|
||||
cellp->has_pixmap = true;
|
||||
for (h = 0; h < CELL_HEIGHT; h++) {
|
||||
src_offset = (y * CELL_HEIGHT + h) * sc->line_length + (CELL_WIDTH * x) * BYTES_PER_PIXEL;
|
||||
dst_offset = h * CELL_WIDTH * BYTES_PER_PIXEL;
|
||||
if (src_offset >= BYTES_PER_PIXEL * term->width * term->height)
|
||||
break;
|
||||
memcpy(cellp->pixmap + dst_offset, sc->pixmap + src_offset, CELL_WIDTH * BYTES_PER_PIXEL);
|
||||
}
|
||||
}
|
||||
move_cursor(term, 1, 0);
|
||||
//set_cursor(term, term->cursor.y + 1, term->cursor.x);
|
||||
}
|
||||
cr(term);
|
||||
}
|
||||
|
||||
void sixel_parse_header(struct terminal_t *term, char *start_buf)
|
||||
{
|
||||
/*
|
||||
sixel format
|
||||
DSC P1; P2; P3; q; s...s; ST
|
||||
parameters
|
||||
DCS: ESC(0x1B) P (0x50) (8bit C1 character not recognized)
|
||||
P1 : pixel aspect ratio (force 0, 2:1) (ignored)
|
||||
P2 : background mode (ignored)
|
||||
0 or 2: 0 stdands for current background color (default)
|
||||
1 : 0 stands for remaining current color
|
||||
P3 : horizontal grid parameter (ignored)
|
||||
q : final character of sixel sequence
|
||||
s : see parse_sixel_data()
|
||||
ST : ESC (0x1B) '\' (0x5C) or BEL (0x07)
|
||||
*/
|
||||
char *cp;
|
||||
struct parm_t parm;
|
||||
|
||||
/* replace final char of sixel header by NUL '\0' */
|
||||
cp = strchr(start_buf, 'q');
|
||||
*cp = '\0';
|
||||
|
||||
logging(DEBUG, "sixel_parse_header()\nbuf:%s\n", start_buf);
|
||||
|
||||
/* split header by semicolon ';' */
|
||||
reset_parm(&parm);
|
||||
parse_arg(start_buf, &parm, ';', isdigit);
|
||||
|
||||
/* set canvas parameters */
|
||||
reset_sixel(&term->sixel, term->color_pair, term->width, term->height);
|
||||
sixel_parse_data(term, &term->sixel, cp + 1); /* skip 'q' */
|
||||
sixel_copy2cell(term, &term->sixel);
|
||||
}
|
||||
|
||||
static inline void decdld_bitmap(struct glyph_t *glyph, uint8_t bitmap, uint8_t row, uint8_t column)
|
||||
{
|
||||
/*
|
||||
MSB LSB (glyph_t bitmap order, padding at LSB side)
|
||||
-> column
|
||||
sixel bit0 ->........
|
||||
sixel bit1 ->........
|
||||
sixel bit2 ->....@@..
|
||||
sixel bit3 ->...@..@.
|
||||
sixel bit4 ->...@....
|
||||
sixel bit5 ->...@....
|
||||
.@@@@@..
|
||||
...@....
|
||||
|...@....
|
||||
row |...@....
|
||||
v...@....
|
||||
...@....
|
||||
...@....
|
||||
...@....
|
||||
........
|
||||
........
|
||||
*/
|
||||
int i, height_shift, width_shift;
|
||||
|
||||
logging(DEBUG, "bit pattern:0x%.2X\n", bitmap);
|
||||
|
||||
width_shift = CELL_WIDTH - 1 - column;
|
||||
if (width_shift < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < BITS_PER_SIXEL; i++) {
|
||||
if((bitmap >> i) & 0x01) {
|
||||
height_shift = row * BITS_PER_SIXEL + i;
|
||||
|
||||
if (height_shift < CELL_HEIGHT) {
|
||||
logging(DEBUG, "height_shift:%d width_shift:%d\n", height_shift, width_shift);
|
||||
glyph->bitmap[height_shift] |= bit_mask[CELL_WIDTH] & (0x01 << width_shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void init_glyph(struct glyph_t *glyph)
|
||||
{
|
||||
int i;
|
||||
|
||||
glyph->width = 1; /* drcs glyph must be HALF */
|
||||
glyph->code = 0; /* this value not used: drcs call by DRCSMMv1 */
|
||||
|
||||
for (i = 0; i < CELL_HEIGHT; i++)
|
||||
glyph->bitmap[i] = 0;
|
||||
}
|
||||
|
||||
void decdld_parse_data(char *start_buf, int start_char, struct glyph_t *chars)
|
||||
{
|
||||
/*
|
||||
DECDLD sixel data
|
||||
';': glyph separator
|
||||
'/': line feed
|
||||
sixel bitmap:
|
||||
range of ? (hex 3F) to ~ (hex 7E)
|
||||
? (hex 3F) represents the binary value 00 0000.
|
||||
t (hex 74) represents the binary value 11 0101.
|
||||
~ (hex 7E) represents the binary value 11 1111.
|
||||
*/
|
||||
char *cp, *end_buf;
|
||||
uint8_t char_num = start_char; /* start_char == 0 means SPACE(0x20) */
|
||||
uint8_t bitmap, row = 0, column = 0;
|
||||
|
||||
init_glyph(&chars[char_num]);
|
||||
cp = start_buf;
|
||||
end_buf = cp + strlen(cp);
|
||||
|
||||
while (cp < end_buf) {
|
||||
if ('?' <= *cp && *cp <= '~') { /* sixel bitmap */
|
||||
logging(DEBUG, "char_num(ten):0x%.2X\n", char_num);
|
||||
/* remove offset '?' and use only 6bit */
|
||||
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
||||
decdld_bitmap(&chars[char_num], bitmap, row, column);
|
||||
column++;
|
||||
} else if (*cp == ';') { /* next char */
|
||||
row = column = 0;
|
||||
char_num++;
|
||||
init_glyph(&chars[char_num]);
|
||||
} else if (*cp == '/') { /* sixel nl+cr */
|
||||
row++;
|
||||
column = 0;
|
||||
} else if (*cp == '\0') { /* end of DECDLD sequence */
|
||||
break;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
void decdld_parse_header(struct terminal_t *term, char *start_buf)
|
||||
{
|
||||
/*
|
||||
DECDLD format
|
||||
DCS Pfn; Pcn; Pe; Pcmw; Pss; Pt; Pcmh; Pcss; f Dscs Sxbp1 ; Sxbp2 ; .. .; Sxbpn ST
|
||||
parameters
|
||||
DCS : ESC (0x1B) 'P' (0x50) (DCS(8bit C1 code) is not supported)
|
||||
Pfn : fontset (ignored)
|
||||
Pcn : start char (0 means SPACE 0x20)
|
||||
Pe : erase mode
|
||||
0: clear selectet charset
|
||||
1: clear only redefined glyph
|
||||
2: clear all drcs charset
|
||||
Pcmw: max cellwidth (force CELL_WEDTH defined in glyph.h)
|
||||
Pss : screen size (ignored)
|
||||
Pt : defines the glyph as text or full cell or sixel (force full cell mode)
|
||||
(TODO: implement sixel/text mode)
|
||||
Pcmh: max cellheight (force CELL_HEIGHT defined in glyph.h)
|
||||
Pcss: character set size (force: 96)
|
||||
0: 94 gylphs charset
|
||||
1: 96 gylphs charset
|
||||
f : '{' (0x7B)
|
||||
Dscs: define character set
|
||||
Intermediate char: SPACE (0x20) to '/' (0x2F)
|
||||
final char : '0' (0x30) to '~' (0x7E)
|
||||
but allow chars between '@' (0x40) and '~' (0x7E) for DRCSMMv1
|
||||
(ref: https://github.com/saitoha/drcsterm/blob/master/README.rst)
|
||||
Sxbp: see parse_decdld_sixel()
|
||||
ST : ESC (0x1B) '\' (0x5C) or BEL (0x07)
|
||||
*/
|
||||
char *cp;
|
||||
int start_char, erase_mode, charset;
|
||||
struct parm_t parm;
|
||||
|
||||
/* replace final char of DECDLD header by NUL '\0' */
|
||||
cp = strchr(start_buf, '{');
|
||||
*cp = '\0';
|
||||
|
||||
logging(DEBUG, "decdld_parse_header()\nbuf:%s\n", start_buf);
|
||||
|
||||
/* split header by semicolon ';' */
|
||||
reset_parm(&parm);
|
||||
parse_arg(start_buf, &parm, ';', isdigit);
|
||||
|
||||
if (parm.argc != 8) /* DECDLD header must have 8 params */
|
||||
return;
|
||||
|
||||
/* set params */
|
||||
start_char = dec2num(parm.argv[1]);
|
||||
erase_mode = dec2num(parm.argv[2]);
|
||||
|
||||
/* parse Dscs */
|
||||
cp++; /* skip final char (NUL) of DECDLD header */
|
||||
while (SPACE <= *cp && *cp <= '/') /* skip intermediate char */
|
||||
cp++;
|
||||
|
||||
if (0x40 <= *cp && *cp <= 0x7E) /* final char of Dscs must be between 0x40 to 0x7E (DRCSMMv1) */
|
||||
charset = *cp - 0x40;
|
||||
else
|
||||
charset = 0;
|
||||
|
||||
logging(DEBUG, "charset(ku):0x%.2X start_char:%d erase_mode:%d\n",
|
||||
charset, start_char, erase_mode);
|
||||
|
||||
/* reset previous glyph data */
|
||||
if (erase_mode < 0 || erase_mode > 2)
|
||||
erase_mode = 0;
|
||||
|
||||
if (erase_mode == 2) /* reset all drcs charset */
|
||||
memset(term->drcs, 0, sizeof(struct glyph_t) * DRCS_CHARS);
|
||||
else if (erase_mode == 0) /* reset selected drcs charset */
|
||||
memset(term->drcs + GLYPHS_PER_CHARSET * charset, 0, sizeof(struct glyph_t) * DRCS_CHARS);
|
||||
|
||||
//if (term->drcs[charset] == NULL) /* always allcate 96 chars buffer */
|
||||
//term->drcs[charset] = ecalloc(GLYPH_PER_CHARSET, sizeof(struct glyph_t));
|
||||
|
||||
decdld_parse_data(cp + 1, start_char, term->drcs + GLYPHS_PER_CHARSET * charset); /* skip final char */
|
||||
}
|
287
ctrlseq/osc.h
287
ctrlseq/osc.h
|
@ -1,287 +0,0 @@
|
|||
/* See LICENSE for licence details. */
|
||||
/* function for osc sequence */
|
||||
int32_t parse_color1(char *seq)
|
||||
{
|
||||
/*
|
||||
format
|
||||
rgb:r/g/b
|
||||
rgb:rr/gg/bb
|
||||
rgb:rrr/ggg/bbb
|
||||
rgb:rrrr/gggg/bbbb
|
||||
*/
|
||||
int i, length, value;
|
||||
int32_t color;
|
||||
uint32_t rgb[3];
|
||||
struct parm_t parm;
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(seq, &parm, '/', isalnum);
|
||||
|
||||
for (i = 0; i < parm.argc; i++)
|
||||
logging(DEBUG, "parm.argv[%d]: %s\n", i, parm.argv[i]);
|
||||
|
||||
if (parm.argc != 3)
|
||||
return -1;
|
||||
|
||||
length = strlen(parm.argv[0]);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
value = hex2num(parm.argv[i]);
|
||||
logging(DEBUG, "value:%d\n", value);
|
||||
|
||||
if (length == 1) /* r/g/b/ */
|
||||
rgb[i] = bit_mask[8] & (value * 0xFF / 0x0F);
|
||||
else if (length == 2) /* rr/gg/bb */
|
||||
rgb[i] = bit_mask[8] & value;
|
||||
else if (length == 3) /* rrr/ggg/bbb */
|
||||
rgb[i] = bit_mask[8] & (value * 0xFF / 0xFFF);
|
||||
else if (length == 4) /* rrrr/gggg/bbbb */
|
||||
rgb[i] = bit_mask[8] & (value * 0xFF / 0xFFFF);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
color = (rgb[0] << 16) + (rgb[1] << 8) + rgb[2];
|
||||
logging(DEBUG, "color:0x%.6X\n", color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
int32_t parse_color2(char *seq)
|
||||
{
|
||||
/*
|
||||
format
|
||||
#rgb
|
||||
#rrggbb
|
||||
#rrrgggbbb
|
||||
#rrrrggggbbbb
|
||||
*/
|
||||
int i, length;
|
||||
uint32_t rgb[3];
|
||||
int32_t color;
|
||||
char buf[BUFSIZE];
|
||||
|
||||
length = strlen(seq);
|
||||
memset(buf, '\0', BUFSIZE);
|
||||
|
||||
if (length == 3) { /* rgb */
|
||||
for (i = 0; i < 3; i++) {
|
||||
strncpy(buf, seq + i, 1);
|
||||
rgb[i] = bit_mask[8] & hex2num(buf) * 0xFF / 0x0F;
|
||||
}
|
||||
} else if (length == 6) { /* rrggbb */
|
||||
for (i = 0; i < 3; i++) { /* rrggbb */
|
||||
strncpy(buf, seq + i * 2, 2);
|
||||
rgb[i] = bit_mask[8] & hex2num(buf);
|
||||
}
|
||||
} else if (length == 9) { /* rrrgggbbb */
|
||||
for (i = 0; i < 3; i++) {
|
||||
strncpy(buf, seq + i * 3, 3);
|
||||
rgb[i] = bit_mask[8] & hex2num(buf) * 0xFF / 0xFFF;
|
||||
}
|
||||
} else if (length == 12) { /* rrrrggggbbbb */
|
||||
for (i = 0; i < 3; i++) {
|
||||
strncpy(buf, seq + i * 4, 4);
|
||||
rgb[i] = bit_mask[8] & hex2num(buf) * 0xFF / 0xFFFF;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
color = (rgb[0] << 16) + (rgb[1] << 8) + rgb[2];
|
||||
logging(DEBUG, "color:0x%.6X\n", color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
void set_palette(struct terminal_t *term, void *arg)
|
||||
{
|
||||
/*
|
||||
OSC Ps ; Pt ST
|
||||
ref: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
|
||||
ref: http://ttssh2.sourceforge.jp/manual/ja/about/ctrlseq.html#OSC
|
||||
|
||||
only recognize change color palette:
|
||||
Ps: 4
|
||||
Pt: c ; spec
|
||||
c: color index (from 0 to 255)
|
||||
spec:
|
||||
rgb:r/g/b
|
||||
rgb:rr/gg/bb
|
||||
rgb:rrr/ggg/bbb
|
||||
rgb:rrrr/gggg/bbbb
|
||||
#rgb
|
||||
#rrggbb
|
||||
#rrrgggbbb
|
||||
#rrrrggggbbbb
|
||||
this rgb format is "RGB Device String Specification"
|
||||
see http://xjman.dsl.gr.jp/X11R6/X11/CH06.html
|
||||
Pt: c ; ?
|
||||
response rgb color
|
||||
OSC 4 ; c ; rgb:rr/gg/bb ST
|
||||
|
||||
TODO: this function only works in 32bpp mode
|
||||
*/
|
||||
struct parm_t *pt = (struct parm_t *) arg;
|
||||
int i, argc = pt->argc, index;
|
||||
int32_t color;
|
||||
uint8_t rgb[3];
|
||||
char **argv = pt->argv;
|
||||
char buf[BUFSIZE];
|
||||
|
||||
if (argc != 3)
|
||||
return;
|
||||
|
||||
index = dec2num(argv[1]);
|
||||
if (index < 0 || index >= COLORS)
|
||||
return;
|
||||
|
||||
if (strncmp(argv[2], "rgb:", 4) == 0) {
|
||||
if ((color = parse_color1(argv[2] + 4)) != -1) { /* skip "rgb:" */
|
||||
term->virtual_palette[index] = (uint32_t) color;
|
||||
term->palette_modified = true;
|
||||
}
|
||||
} else if (strncmp(argv[2], "#", 1) == 0) {
|
||||
if ((color = parse_color2(argv[2] + 1)) != -1) { /* skip "#" */
|
||||
term->virtual_palette[index] = (uint32_t) color;
|
||||
term->palette_modified = true;
|
||||
}
|
||||
} else if (strncmp(argv[2], "?", 1) == 0) {
|
||||
for (i = 0; i < 3; i++)
|
||||
rgb[i] = bit_mask[8] & (term->virtual_palette[index] >> (8 * (2 - i)));
|
||||
|
||||
snprintf(buf, BUFSIZE, "\033]4;%d;rgb:%.2X/%.2X/%.2X\033\\",
|
||||
index, rgb[0], rgb[1], rgb[2]);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
|
||||
void reset_palette(struct terminal_t *term, void *arg)
|
||||
{
|
||||
/*
|
||||
reset color c
|
||||
OSC 104 ; c ST
|
||||
c: index of color
|
||||
ST: BEL or ESC \
|
||||
reset all color
|
||||
OSC 104 ST
|
||||
ST: BEL or ESC \
|
||||
|
||||
terminfo: oc=\E]104\E\\
|
||||
*/
|
||||
struct parm_t *pt = (struct parm_t *) arg;
|
||||
int i, argc = pt->argc, c;
|
||||
char **argv = pt->argv;
|
||||
|
||||
if (argc < 2) { /* reset all color palette */
|
||||
for (i = 0; i < COLORS; i++)
|
||||
term->virtual_palette[i] = color_list[i];
|
||||
term->palette_modified = true;
|
||||
} else if (argc == 2) { /* reset color_palette[c] */
|
||||
c = dec2num(argv[1]);
|
||||
if (0 <= c && c < COLORS) {
|
||||
term->virtual_palette[c] = color_list[c];
|
||||
term->palette_modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int isdigit_or_questionmark(int c)
|
||||
{
|
||||
if (isdigit(c) || c == '?')
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void glyph_width_report(struct terminal_t *term, void *arg)
|
||||
{
|
||||
/*
|
||||
glyph width report
|
||||
* request *
|
||||
OSC 8900 ; Ps ; Pw ; ? : Pf : Pt ST
|
||||
Ps: reserved
|
||||
Pw: width (0 or 1 or 2)
|
||||
Pfrom: beginning of unicode code point
|
||||
Pto: end of unicode code point
|
||||
ST: BEL(0x07) or ESC(0x1B) BACKSLASH(0x5C)
|
||||
* answer *
|
||||
OSC 8900 ; Ps ; Pv ; Pw ; Pf : Pt ; Pf : Pt ; ... ST
|
||||
Ps: responce code
|
||||
0: ok (default)
|
||||
1: recognized but not supported
|
||||
2: not recognized
|
||||
Pv: reserved (maybe East Asian Width Version)
|
||||
Pw: width (0 or 1 or 2)
|
||||
Pfrom: beginning of unicode code point
|
||||
Pto: end of unicode code point
|
||||
ST: BEL(0x07) or ESC(0x1B) BACKSLASH(0x5C)
|
||||
ref
|
||||
http://uobikiemukot.github.io/yaft/glyph_width_report.html
|
||||
https://gist.github.com/saitoha/8767268
|
||||
*/
|
||||
struct parm_t *pt = (struct parm_t *) arg, sub_parm;
|
||||
int i, argc = pt->argc, width, from, to, left, right, w, wcw; //reserved
|
||||
char **argv = pt->argv, buf[BUFSIZE];
|
||||
|
||||
if (argc < 4)
|
||||
return;
|
||||
|
||||
reset_parm(&sub_parm);
|
||||
parse_arg(argv[3], &sub_parm, ':', isdigit_or_questionmark);
|
||||
|
||||
if (sub_parm.argc != 3 || *sub_parm.argv[0] != '?')
|
||||
return;
|
||||
|
||||
//reserved = dec2num(argv[1]);
|
||||
width = dec2num(argv[2]);
|
||||
from = dec2num(sub_parm.argv[1]);
|
||||
to = dec2num(sub_parm.argv[2]);
|
||||
|
||||
if ((width < 0) || (width > 2))
|
||||
return;
|
||||
|
||||
/* unicode private area: plane 16 (DRCSMMv1) is always half */
|
||||
if ((from < 0) || (to >= UCS2_CHARS))
|
||||
return;
|
||||
|
||||
snprintf(buf, BUFSIZE, "\033]8900;0;0;%d;", width); /* OSC 8900 ; Ps; Pv ; Pw ; */
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
|
||||
left = right = -1;
|
||||
for (i = from; i <= to; i++) {
|
||||
wcw = wcwidth(i);
|
||||
if (wcw <= 0) /* zero width */
|
||||
w = 0;
|
||||
else if (term->glyph[i] == NULL) /* missing glyph */
|
||||
w = wcw;
|
||||
else
|
||||
w = term->glyph[i]->width;
|
||||
|
||||
if (w != width) {
|
||||
if (right != -1) {
|
||||
snprintf(buf, BUFSIZE, "%d:%d;", left, right);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
} else if (left != -1) {
|
||||
snprintf(buf, BUFSIZE, "%d:%d;", left, left);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
}
|
||||
left = right = -1;
|
||||
} else {
|
||||
if (left == -1)
|
||||
left = i;
|
||||
else
|
||||
right = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (right != -1) {
|
||||
snprintf(buf, BUFSIZE, "%d:%d;", left, right);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
} else if (left != -1) {
|
||||
snprintf(buf, BUFSIZE, "%d:%d;", left, left);
|
||||
ewrite(term->fd, buf, strlen(buf));
|
||||
}
|
||||
|
||||
ewrite(term->fd, "\033\\", 2); /* ST (ESC BACKSLASH) */
|
||||
}
|
31
fb/common.h
31
fb/common.h
|
@ -170,7 +170,6 @@ static inline uint32_t color2pixel(struct fb_info_t *info, uint32_t color)
|
|||
+ (b << info->blue.offset);
|
||||
}
|
||||
|
||||
|
||||
bool init_truecolor(struct fb_info_t *info, cmap_t **cmap, cmap_t **cmap_orig)
|
||||
{
|
||||
switch(info->bits_per_pixel) {
|
||||
|
@ -364,24 +363,6 @@ void fb_die(struct framebuffer_t *fb)
|
|||
//fb_release(fb->fd, &fb->info); /* os specific */
|
||||
}
|
||||
|
||||
static inline void draw_sixel(struct framebuffer_t *fb, int line, int col, uint8_t *pixmap)
|
||||
{
|
||||
int h, w, src_offset, dst_offset;
|
||||
uint32_t pixel, color = 0;
|
||||
|
||||
for (h = 0; h < CELL_HEIGHT; h++) {
|
||||
for (w = 0; w < CELL_WIDTH; w++) {
|
||||
src_offset = BYTES_PER_PIXEL * (h * CELL_WIDTH + w);
|
||||
memcpy(&color, pixmap + src_offset, BYTES_PER_PIXEL);
|
||||
|
||||
dst_offset = (line * CELL_HEIGHT + h) * fb->info.line_length
|
||||
+ (col * CELL_WIDTH + w) * fb->info.bytes_per_pixel;
|
||||
pixel = color2pixel(&fb->info, color);
|
||||
memcpy(fb->buf + dst_offset, &pixel, fb->info.bytes_per_pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void draw_line(struct framebuffer_t *fb, struct terminal_t *term, int line)
|
||||
{
|
||||
int pos, size, bdf_padding, glyph_width, margin_right;
|
||||
|
@ -396,12 +377,6 @@ static inline void draw_line(struct framebuffer_t *fb, struct terminal_t *term,
|
|||
/* target cell */
|
||||
cellp = &term->cells[line][col];
|
||||
|
||||
/* draw sixel pixmap */
|
||||
if (cellp->has_pixmap) {
|
||||
draw_sixel(fb, line, col, cellp->pixmap);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* copy current color_pair (maybe changed) */
|
||||
color_pair = cellp->color_pair;
|
||||
|
||||
|
@ -460,12 +435,6 @@ static inline void draw_line(struct framebuffer_t *fb, struct terminal_t *term,
|
|||
|
||||
void refresh(struct framebuffer_t *fb, struct terminal_t *term)
|
||||
{
|
||||
if (term->palette_modified) {
|
||||
term->palette_modified = false;
|
||||
for (int i = 0; i < COLORS; i++)
|
||||
fb->real_palette[i] = color2pixel(&fb->info, term->virtual_palette[i]);
|
||||
}
|
||||
|
||||
if (term->mode & MODE_CURSOR)
|
||||
term->line_dirty[term->cursor.y] = true;
|
||||
|
||||
|
|
2
makefile
2
makefile
|
@ -8,7 +8,7 @@ XCFLAGS ?= -std=c99 -pedantic -Wall -Wextra -I/usr/include/X11/ -O3 -s -pipe
|
|||
XLDFLAGS ?= -lX11
|
||||
|
||||
HDR = glyph.h yaft.h conf.h color.h parse.h terminal.h util.h \
|
||||
ctrlseq/esc.h ctrlseq/csi.h ctrlseq/osc.h ctrlseq/dcs.h \
|
||||
ctrlseq/esc.h ctrlseq/csi.h \
|
||||
fb/common.h fb/linux.h fb/freebsd.h fb/netbsd.h fb/openbsd.h \
|
||||
x/x.h
|
||||
|
||||
|
|
66
parse.h
66
parse.h
|
@ -108,79 +108,17 @@ void csi_sequence(struct terminal_t *term, uint8_t ch)
|
|||
reset_esc(term);
|
||||
}
|
||||
|
||||
int is_osc_parm(int c)
|
||||
{
|
||||
if (isdigit(c) || isalpha(c) ||
|
||||
c == '?' || c == ':' || c == '/' || c == '#')
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void omit_string_terminator(char *bp, uint8_t ch)
|
||||
{
|
||||
if (ch == BACKSLASH) /* ST: ESC BACKSLASH */
|
||||
*(bp - 2) = '\0';
|
||||
else /* ST: BEL */
|
||||
*(bp - 1) = '\0';
|
||||
}
|
||||
|
||||
void osc_sequence(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
int osc_mode;
|
||||
struct parm_t parm;
|
||||
|
||||
omit_string_terminator(term->esc.bp, ch);
|
||||
|
||||
(void) ch;
|
||||
logging(DEBUG, "osc: OSC %s\n", term->esc.buf);
|
||||
|
||||
reset_parm(&parm);
|
||||
parse_arg(term->esc.buf + 1, &parm, ';', is_osc_parm); /* skip ']' */
|
||||
|
||||
if (parm.argc > 0) {
|
||||
osc_mode = dec2num(parm.argv[0]);
|
||||
logging(DEBUG, "osc_mode:%d\n", osc_mode);
|
||||
|
||||
/* XXX: disable because this functions only work 24/32bpp
|
||||
-> support other bpp (including pseudo color) */
|
||||
if (osc_mode == 4)
|
||||
set_palette(term, &parm);
|
||||
else if (osc_mode == 104)
|
||||
reset_palette(term, &parm);
|
||||
if (osc_mode == 8900)
|
||||
glyph_width_report(term, &parm);
|
||||
}
|
||||
reset_esc(term);
|
||||
}
|
||||
|
||||
void dcs_sequence(struct terminal_t *term, uint8_t ch)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
omit_string_terminator(term->esc.bp, ch);
|
||||
|
||||
(void) ch;
|
||||
logging(DEBUG, "dcs: DCS %s\n", term->esc.buf);
|
||||
|
||||
/* check DCS header */
|
||||
cp = term->esc.buf + 1; /* skip P */
|
||||
while (cp < term->esc.bp) {
|
||||
if (*cp == '{' || *cp == 'q') /* DECDLD or sixel */
|
||||
break;
|
||||
else if (*cp == ';' || ('0' <= *cp && *cp <= '9')) /* valid DCS header */
|
||||
;
|
||||
else /* invalid sequence */
|
||||
cp = term->esc.bp;
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (cp != term->esc.bp) { /* header only or couldn't find final char */
|
||||
/* parse DCS header */
|
||||
if (*cp == 'q')
|
||||
sixel_parse_header(term, term->esc.buf + 1);
|
||||
else if (*cp == '{')
|
||||
decdld_parse_header(term, term->esc.buf + 1);
|
||||
}
|
||||
|
||||
reset_esc(term);
|
||||
}
|
||||
|
||||
|
|
38
terminal.h
38
terminal.h
|
@ -8,7 +8,6 @@ void erase_cell(struct terminal_t *term, int y, int x)
|
|||
cellp->color_pair = term->color_pair; /* bce */
|
||||
cellp->attribute = ATTR_RESET;
|
||||
cellp->width = HALF;
|
||||
cellp->has_pixmap = false;
|
||||
|
||||
term->line_dirty[y] = true;
|
||||
}
|
||||
|
@ -54,7 +53,6 @@ int set_cell(struct terminal_t *term, int y, int x, const struct glyph_t *glyphp
|
|||
|
||||
cell.attribute = term->attribute;
|
||||
cell.width = glyphp->width;
|
||||
cell.has_pixmap = false;
|
||||
|
||||
cellp = &term->cells[y][x];
|
||||
*cellp = cell;
|
||||
|
@ -170,25 +168,6 @@ void set_cursor(struct terminal_t *term, int y, int x)
|
|||
term->wrap_occured = false;
|
||||
}
|
||||
|
||||
const struct glyph_t *drcs_glyph(struct terminal_t *term, uint32_t code)
|
||||
{
|
||||
/* DRCSMMv1
|
||||
ESC ( SP <\xXX> <\xYY> ESC ( B
|
||||
<===> U+10XXYY ( 0x40 <= 0xXX <=0x7E, 0x20 <= 0xYY <= 0x7F )
|
||||
*/
|
||||
int row, cell; /* = ku, ten */
|
||||
|
||||
row = (0xFF00 & code) >> 8;
|
||||
cell = 0xFF & code;
|
||||
|
||||
logging(DEBUG, "drcs row:0x%.2X cell:0x%.2X\n", row, cell);
|
||||
|
||||
if ((0x40 <= row && row <= 0x7E) && (0x20 <= cell && cell <= 0x7F))
|
||||
return &term->drcs[(row - 0x40) * GLYPHS_PER_CHARSET + (cell - 0x20)];
|
||||
else
|
||||
return term->glyph[SUBSTITUTE_HALF];
|
||||
}
|
||||
|
||||
void addch(struct terminal_t *term, uint32_t code)
|
||||
{
|
||||
int width;
|
||||
|
@ -198,11 +177,9 @@ void addch(struct terminal_t *term, uint32_t code)
|
|||
|
||||
width = wcwidth(code);
|
||||
|
||||
if (width <= 0) /* zero width: not support comibining character */
|
||||
if (width <= 0) /* zero width: not support comibining character */
|
||||
return;
|
||||
else if (0x100000 <= code && code <= 0x10FFFD) /* unicode private area: plane 16 (DRCSMMv1) */
|
||||
glyphp = drcs_glyph(term, code);
|
||||
else if (code >= UCS2_CHARS /* yaft support only UCS2 */
|
||||
else if (code >= UCS2_CHARS /* yaft support only UCS2 */
|
||||
|| term->glyph[code] == NULL /* missing glyph */
|
||||
|| term->glyph[code]->width != width) /* width unmatch */
|
||||
glyphp = (width == 1) ? term->glyph[SUBSTITUTE_HALF]: term->glyph[SUBSTITUTE_WIDE];
|
||||
|
@ -335,7 +312,6 @@ void term_die(struct terminal_t *term)
|
|||
free(term->line_dirty);
|
||||
free(term->tabstop);
|
||||
free(term->esc.buf);
|
||||
free(term->sixel.pixmap);
|
||||
|
||||
for (int i = 0; i < term->lines; i++)
|
||||
free(term->cells[i]);
|
||||
|
@ -360,23 +336,17 @@ bool term_init(struct terminal_t *term, int width, int height)
|
|||
term->line_dirty = (bool *) ecalloc(term->lines, sizeof(bool));
|
||||
term->tabstop = (bool *) ecalloc(term->cols, sizeof(bool));
|
||||
term->esc.buf = (char *) ecalloc(1, term->esc.size);
|
||||
term->sixel.pixmap = (uint8_t *) ecalloc(width * height, BYTES_PER_PIXEL);
|
||||
|
||||
term->cells = (struct cell_t **) ecalloc(term->lines, sizeof(struct cell_t *));
|
||||
for (int i = 0; i < term->lines; i++)
|
||||
term->cells[i] = (struct cell_t *) ecalloc(term->cols, sizeof(struct cell_t));
|
||||
|
||||
if (!term->line_dirty || !term->tabstop || !term->cells
|
||||
|| !term->esc.buf || !term->sixel.pixmap) {
|
||||
if (!term->line_dirty || !term->tabstop
|
||||
|| !term->cells || !term->esc.buf) {
|
||||
term_die(term);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* initialize palette */
|
||||
for (int i = 0; i < COLORS; i++)
|
||||
term->virtual_palette[i] = color_list[i];
|
||||
term->palette_modified = false;
|
||||
|
||||
/* initialize glyph map */
|
||||
for (uint32_t code = 0; code < UCS2_CHARS; code++)
|
||||
term->glyph[code] = NULL;
|
||||
|
|
2
yaft.c
2
yaft.c
|
@ -7,8 +7,6 @@
|
|||
#include "terminal.h"
|
||||
#include "ctrlseq/esc.h"
|
||||
#include "ctrlseq/csi.h"
|
||||
#include "ctrlseq/osc.h"
|
||||
#include "ctrlseq/dcs.h"
|
||||
#include "parse.h"
|
||||
|
||||
void sig_handler(int signo)
|
||||
|
|
27
yaft.h
27
yaft.h
|
@ -36,8 +36,6 @@ enum char_code {
|
|||
enum misc {
|
||||
BUFSIZE = 1024, /* read, esc, various buffer size */
|
||||
BITS_PER_BYTE = 8, /* bits per byte */
|
||||
BYTES_PER_PIXEL = sizeof(uint32_t), /* pixel size of sixel pixmap data */
|
||||
BITS_PER_SIXEL = 6, /* number of bits of a sixel */
|
||||
ESCSEQ_SIZE = 1024, /* limit size of terminal escape sequence */
|
||||
SELECT_TIMEOUT = 15000, /* used by select() */
|
||||
SLEEP_TIME = 30000, /* sleep time at EAGAIN, EWOULDBLOCK (usec) */
|
||||
|
@ -45,9 +43,6 @@ enum misc {
|
|||
UCS2_CHARS = 0x10000, /* number of UCS2 glyphs */
|
||||
CTRL_CHARS = 0x20, /* number of ctrl_func */
|
||||
ESC_CHARS = 0x80, /* number of esc_func */
|
||||
DRCS_CHARSETS = 63, /* number of charset of DRCS (according to DRCSMMv1) */
|
||||
GLYPHS_PER_CHARSET = 96, /* number of glyph of each DRCS charset */
|
||||
DRCS_CHARS = DRCS_CHARSETS * GLYPHS_PER_CHARSET,
|
||||
DEFAULT_CHAR = SPACE, /* used for erase char */
|
||||
BRIGHT_INC = 8, /* value used for brightening color */
|
||||
};
|
||||
|
@ -112,10 +107,6 @@ struct cell_t {
|
|||
struct color_pair_t color_pair; /* color (fg, bg) */
|
||||
enum char_attr attribute; /* bold, underscore, etc... */
|
||||
enum glyph_width width; /* wide char flag: WIDE, NEXT_TO_WIDE, HALF */
|
||||
bool has_pixmap; /* has sixel pixmap data or not */
|
||||
/* sixel pixmap data:
|
||||
must be statically allocated for copy_cell() */
|
||||
uint8_t pixmap[BYTES_PER_PIXEL * CELL_WIDTH * CELL_HEIGHT];
|
||||
};
|
||||
|
||||
struct esc_t {
|
||||
|
@ -126,8 +117,9 @@ struct esc_t {
|
|||
};
|
||||
|
||||
struct charset_t {
|
||||
uint32_t code; /* UCS4 code point: yaft only prints UCS2 and DRCSMMv1 */
|
||||
int following_byte, count;
|
||||
uint32_t code; /* UCS2 code point: yaft only supports BMP */
|
||||
int following_byte;
|
||||
int count;
|
||||
bool is_valid;
|
||||
};
|
||||
|
||||
|
@ -137,15 +129,6 @@ struct state_t { /* for save, restore state */
|
|||
enum char_attr attribute;
|
||||
};
|
||||
|
||||
struct sixel_canvas_t {
|
||||
uint8_t *pixmap;
|
||||
struct point_t point;
|
||||
int width, height;
|
||||
int line_length;
|
||||
uint8_t color_index;
|
||||
uint32_t color_table[COLORS];
|
||||
};
|
||||
|
||||
struct terminal_t {
|
||||
int fd; /* master of pseudo terminal */
|
||||
int width, height; /* terminal size (pixel) */
|
||||
|
@ -162,11 +145,7 @@ struct terminal_t {
|
|||
enum char_attr attribute; /* bold, underscore, etc... */
|
||||
struct charset_t charset; /* store UTF-8 byte stream */
|
||||
struct esc_t esc; /* store escape sequence */
|
||||
uint32_t virtual_palette[COLORS]; /* virtual color palette: always 32bpp */
|
||||
bool palette_modified; /* true if palette changed by OSC 4/104 */
|
||||
const struct glyph_t *glyph[UCS2_CHARS]; /* array of pointer to glyphs[] */
|
||||
struct glyph_t drcs[DRCS_CHARS]; /* DRCS chars */
|
||||
struct sixel_canvas_t sixel;
|
||||
};
|
||||
|
||||
struct parm_t { /* for parse_arg() */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue