version 1.126, 2022/07/06 07:36:36 |
version 1.127, 2022/09/28 07:55:29 |
|
|
/* Add on SGR code. */ |
/* Add on SGR code. */ |
static void |
static void |
grid_string_cells_add_code(char *buf, size_t len, u_int n, int *s, int *newc, |
grid_string_cells_add_code(char *buf, size_t len, u_int n, int *s, int *newc, |
int *oldc, size_t nnewc, size_t noldc, int escape_c0) |
int *oldc, size_t nnewc, size_t noldc, int flags) |
{ |
{ |
u_int i; |
u_int i; |
char tmp[64]; |
char tmp[64]; |
|
int reset = (n != 0 && s[0] == 0); |
|
|
if (nnewc != 0 && |
if (nnewc == 0) |
(nnewc != noldc || |
return; /* no code to add */ |
memcmp(newc, oldc, nnewc * sizeof newc[0]) != 0 || |
if (!reset && |
(n != 0 && s[0] == 0))) { |
nnewc == noldc && |
if (escape_c0) |
memcmp(newc, oldc, nnewc * sizeof newc[0]) == 0) |
strlcat(buf, "\\033[", len); |
return; /* no reset and colour unchanged */ |
|
if (reset && (newc[0] == 49 || newc[0] == 39)) |
|
return; /* reset and colour default */ |
|
|
|
if (flags & GRID_STRING_ESCAPE_SEQUENCES) |
|
strlcat(buf, "\\033[", len); |
|
else |
|
strlcat(buf, "\033[", len); |
|
for (i = 0; i < nnewc; i++) { |
|
if (i + 1 < nnewc) |
|
xsnprintf(tmp, sizeof tmp, "%d;", newc[i]); |
else |
else |
strlcat(buf, "\033[", len); |
xsnprintf(tmp, sizeof tmp, "%d", newc[i]); |
for (i = 0; i < nnewc; i++) { |
strlcat(buf, tmp, len); |
if (i + 1 < nnewc) |
|
xsnprintf(tmp, sizeof tmp, "%d;", newc[i]); |
|
else |
|
xsnprintf(tmp, sizeof tmp, "%d", newc[i]); |
|
strlcat(buf, tmp, len); |
|
} |
|
strlcat(buf, "m", len); |
|
} |
} |
|
strlcat(buf, "m", len); |
} |
} |
|
|
static int |
static int |
grid_string_cells_add_hyperlink(char *buf, size_t len, const char *id, |
grid_string_cells_add_hyperlink(char *buf, size_t len, const char *id, |
const char *uri, int escape_c0) |
const char *uri, int flags) |
{ |
{ |
char *tmp; |
char *tmp; |
|
|
if (strlen(uri) + strlen(id) + 17 >= len) |
if (strlen(uri) + strlen(id) + 17 >= len) |
return (0); |
return (0); |
|
|
if (escape_c0) |
if (flags & GRID_STRING_ESCAPE_SEQUENCES) |
strlcat(buf, "\\033]8;", len); |
strlcat(buf, "\\033]8;", len); |
else |
else |
strlcat(buf, "\033]8;", len); |
strlcat(buf, "\033]8;", len); |
|
|
} else |
} else |
strlcat(buf, ";", len); |
strlcat(buf, ";", len); |
strlcat(buf, uri, len); |
strlcat(buf, uri, len); |
if (escape_c0) |
if (flags & GRID_STRING_ESCAPE_SEQUENCES) |
strlcat(buf, "\\033\\\\", len); |
strlcat(buf, "\\033\\\\", len); |
else |
else |
strlcat(buf, "\033\\", len); |
strlcat(buf, "\033\\", len); |
|
|
*/ |
*/ |
static void |
static void |
grid_string_cells_code(const struct grid_cell *lastgc, |
grid_string_cells_code(const struct grid_cell *lastgc, |
const struct grid_cell *gc, char *buf, size_t len, int escape_c0, |
const struct grid_cell *gc, char *buf, size_t len, int flags, |
struct screen *sc, int *has_link) |
struct screen *sc, int *has_link) |
{ |
{ |
int oldc[64], newc[64], s[128]; |
int oldc[64], newc[64], s[128]; |
|
|
char tmp[64]; |
char tmp[64]; |
const char *uri, *id; |
const char *uri, *id; |
|
|
struct { |
static const struct { |
u_int mask; |
u_int mask; |
u_int code; |
u_int code; |
} attrs[] = { |
} attrs[] = { |
|
|
/* Write the attributes. */ |
/* Write the attributes. */ |
*buf = '\0'; |
*buf = '\0'; |
if (n > 0) { |
if (n > 0) { |
if (escape_c0) |
if (flags & GRID_STRING_ESCAPE_SEQUENCES) |
strlcat(buf, "\\033[", len); |
strlcat(buf, "\\033[", len); |
else |
else |
strlcat(buf, "\033[", len); |
strlcat(buf, "\033[", len); |
|
|
nnewc = grid_string_cells_fg(gc, newc); |
nnewc = grid_string_cells_fg(gc, newc); |
noldc = grid_string_cells_fg(lastgc, oldc); |
noldc = grid_string_cells_fg(lastgc, oldc); |
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, |
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, |
escape_c0); |
flags); |
|
|
/* If the background colour changed, append its parameters. */ |
/* If the background colour changed, append its parameters. */ |
nnewc = grid_string_cells_bg(gc, newc); |
nnewc = grid_string_cells_bg(gc, newc); |
noldc = grid_string_cells_bg(lastgc, oldc); |
noldc = grid_string_cells_bg(lastgc, oldc); |
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, |
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, |
escape_c0); |
flags); |
|
|
/* If the underscore colour changed, append its parameters. */ |
/* If the underscore colour changed, append its parameters. */ |
nnewc = grid_string_cells_us(gc, newc); |
nnewc = grid_string_cells_us(gc, newc); |
noldc = grid_string_cells_us(lastgc, oldc); |
noldc = grid_string_cells_us(lastgc, oldc); |
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, |
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, |
escape_c0); |
flags); |
|
|
/* Append shift in/shift out if needed. */ |
/* Append shift in/shift out if needed. */ |
if ((attr & GRID_ATTR_CHARSET) && !(lastattr & GRID_ATTR_CHARSET)) { |
if ((attr & GRID_ATTR_CHARSET) && !(lastattr & GRID_ATTR_CHARSET)) { |
if (escape_c0) |
if (flags & GRID_STRING_ESCAPE_SEQUENCES) |
strlcat(buf, "\\016", len); /* SO */ |
strlcat(buf, "\\016", len); /* SO */ |
else |
else |
strlcat(buf, "\016", len); /* SO */ |
strlcat(buf, "\016", len); /* SO */ |
} |
} |
if (!(attr & GRID_ATTR_CHARSET) && (lastattr & GRID_ATTR_CHARSET)) { |
if (!(attr & GRID_ATTR_CHARSET) && (lastattr & GRID_ATTR_CHARSET)) { |
if (escape_c0) |
if (flags & GRID_STRING_ESCAPE_SEQUENCES) |
strlcat(buf, "\\017", len); /* SI */ |
strlcat(buf, "\\017", len); /* SI */ |
else |
else |
strlcat(buf, "\017", len); /* SI */ |
strlcat(buf, "\017", len); /* SI */ |
|
|
if (sc != NULL && sc->hyperlinks != NULL && lastgc->link != gc->link) { |
if (sc != NULL && sc->hyperlinks != NULL && lastgc->link != gc->link) { |
if (hyperlinks_get(sc->hyperlinks, gc->link, &uri, &id, NULL)) { |
if (hyperlinks_get(sc->hyperlinks, gc->link, &uri, &id, NULL)) { |
*has_link = grid_string_cells_add_hyperlink(buf, len, |
*has_link = grid_string_cells_add_hyperlink(buf, len, |
id, uri, escape_c0); |
id, uri, flags); |
} else if (*has_link) { |
} else if (*has_link) { |
grid_string_cells_add_hyperlink(buf, len, "", "", |
grid_string_cells_add_hyperlink(buf, len, "", "", |
escape_c0); |
flags); |
*has_link = 0; |
*has_link = 0; |
} |
} |
} |
} |
|
|
/* Convert cells into a string. */ |
/* Convert cells into a string. */ |
char * |
char * |
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, |
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, |
struct grid_cell **lastgc, int with_codes, int escape_c0, int trim, |
struct grid_cell **lastgc, int flags, struct screen *s) |
struct screen *s) |
|
{ |
{ |
struct grid_cell gc; |
struct grid_cell gc; |
static struct grid_cell lastgc1; |
static struct grid_cell lastgc1; |
const char *data; |
const char *data; |
char *buf, code[8192]; |
char *buf, code[8192]; |
size_t len, off, size, codelen; |
size_t len, off, size, codelen; |
u_int xx, has_link = 0; |
u_int xx, has_link = 0, end; |
const struct grid_line *gl; |
const struct grid_line *gl; |
|
|
if (lastgc != NULL && *lastgc == NULL) { |
if (lastgc != NULL && *lastgc == NULL) { |
|
|
off = 0; |
off = 0; |
|
|
gl = grid_peek_line(gd, py); |
gl = grid_peek_line(gd, py); |
|
if (flags & GRID_STRING_EMPTY_CELLS) |
|
end = gl->cellsize; |
|
else |
|
end = gl->cellused; |
for (xx = px; xx < px + nx; xx++) { |
for (xx = px; xx < px + nx; xx++) { |
if (gl == NULL || xx >= gl->cellused) |
if (gl == NULL || xx >= end) |
break; |
break; |
grid_get_cell(gd, xx, py, &gc); |
grid_get_cell(gd, xx, py, &gc); |
if (gc.flags & GRID_FLAG_PADDING) |
if (gc.flags & GRID_FLAG_PADDING) |
continue; |
continue; |
|
|
if (with_codes) { |
if (flags & GRID_STRING_WITH_SEQUENCES) { |
grid_string_cells_code(*lastgc, &gc, code, sizeof code, |
grid_string_cells_code(*lastgc, &gc, code, sizeof code, |
escape_c0, s, &has_link); |
flags, s, &has_link); |
codelen = strlen(code); |
codelen = strlen(code); |
memcpy(*lastgc, &gc, sizeof **lastgc); |
memcpy(*lastgc, &gc, sizeof **lastgc); |
} else |
} else |
|
|
|
|
data = gc.data.data; |
data = gc.data.data; |
size = gc.data.size; |
size = gc.data.size; |
if (escape_c0 && size == 1 && *data == '\\') { |
if ((flags & GRID_STRING_ESCAPE_SEQUENCES) && |
|
size == 1 && |
|
*data == '\\') { |
data = "\\\\"; |
data = "\\\\"; |
size = 2; |
size = 2; |
} |
} |
|
|
|
|
if (has_link) { |
if (has_link) { |
grid_string_cells_add_hyperlink(code, sizeof code, "", "", |
grid_string_cells_add_hyperlink(code, sizeof code, "", "", |
escape_c0); |
flags); |
codelen = strlen(code); |
codelen = strlen(code); |
while (len < off + size + codelen + 1) { |
while (len < off + size + codelen + 1) { |
buf = xreallocarray(buf, 2, len); |
buf = xreallocarray(buf, 2, len); |
|
|
off += codelen; |
off += codelen; |
} |
} |
|
|
if (trim) { |
if (flags & GRID_STRING_TRIM_SPACES) { |
while (off > 0 && buf[off - 1] == ' ') |
while (off > 0 && buf[off - 1] == ' ') |
off--; |
off--; |
} |
} |