set quadrants for linux console only if we reprogrammed the font, or found them

pull/1838/head
nick black 3 years ago
parent 5c0f06eaf3
commit 8fe8e35efe
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -37,12 +37,6 @@ braille_viz(ncplane* n, const char* l, const wchar_t* egcs, const char* r, const
static int static int
unicodedumper(struct ncplane* n, tinfo* ti, const char* indent){ unicodedumper(struct ncplane* n, tinfo* ti, const char* indent){
if(ti->caps.utf8){ if(ti->caps.utf8){
/*uint32_t l = CHANNEL_RGB_INITIALIZER(0x20, 0x20, 0x20);
uint32_t r = CHANNEL_RGB_INITIALIZER(0x80, 0x80, 0x80);
int y, x;
ncplane_cursor_yx(n, &y, &x);
ncplane_highgradient_sized(n, l, r, l, r, 10, ncplane_dim_x(n));
ncplane_cursor_move_yx(n, y, x);*/
ncplane_printf(n, " {%ls} {%ls} ⎧%.122ls⎫ ⎧█ ⎫ 🯰🯱\n", ncplane_printf(n, " {%ls} {%ls} ⎧%.122ls⎫ ⎧█ ⎫ 🯰🯱\n",
NCHALFBLOCKS, NCQUADBLOCKS, NCSEXBLOCKS); NCHALFBLOCKS, NCQUADBLOCKS, NCSEXBLOCKS);
ncplane_printf(n, " ⎩%ls⎭ ⎪🮋▏⎪ 🯲🯳\n", ncplane_printf(n, " ⎩%ls⎭ ⎪🮋▏⎪ 🯲🯳\n",
@ -65,17 +59,17 @@ unicodedumper(struct ncplane* n, tinfo* ti, const char* indent){
ncplane_printf(n, "⎪🮇▊⎪\n"); ncplane_printf(n, "⎪🮇▊⎪\n");
braille_viz(n, "",NCBRAILLEEGCS + 192, "", indent); braille_viz(n, "",NCBRAILLEEGCS + 192, "", indent);
ncplane_printf(n, "⎪▕▉⎪\n"); ncplane_printf(n, "⎪▕▉⎪\n");
ncplane_printf(n, "%s⎛%ls⎞ ▔🭶🭷🭸🭹🭺🭻▁ 🭁 🭂 🭃 🭄 🭅 🭆 🭑 🭐 🭏 🭎 🭍 🭌 🭆🭑 🭄🭏 🭅🭐 🭃🭎 🭂🭍 🭁🭌 🭨🭪 ⎩ █⎭\n", ncplane_printf(n, "%s⎛%ls⎞ ▔🭶🭷🭸🭹🭺🭻▁ 🭁 🭂 🭃 🭄 🭅 🭆 🭑 🭐 🭏 🭎 🭍 🭌 🭆🭑 🭄🭏 🭅🭐 🭃🭎 🭂🭍 🭁🭌 🭨🭪 ⎩ █⎭\n",
indent, NCEIGHTHSBOTTOM); indent, NCEIGHTHSBOTTOM);
ncplane_printf(n, "%s⎝%ls⎠ ▏🭰🭱🭲🭳🭴🭵▕ 🭒 🭓 🭔 🭕 🭖 🭧 🭜 🭟 🭠 🭡 🭞 🭝 🭧🭜 🭕🭠 🭖🭡 🭔🭟 🭓🭞 🭒🭝 🭪🭨 \n", ncplane_printf(n, "%s⎝%ls⎠ ▏🭰🭱🭲🭳🭴🭵▕ 🭒 🭓 🭔 🭕 🭖 🭧 🭜 🭟 🭠 🭡 🭞 🭝 🭧🭜 🭕🭠 🭖🭡 🭔🭟 🭓🭞 🭒🭝 🭪🭨 \n",
indent, NCEIGHTSTOP); indent, NCEIGHTSTOP);
int y, x; int y, x;
ncplane_cursor_yx(n, &y, &x); ncplane_cursor_yx(n, &y, &x);
// the symbols for legacy computing // the symbols for legacy computing
ncplane_cursor_move_yx(n, y - 2, 23); ncplane_cursor_move_yx(n, y - 2, 12);
uint32_t ul = CHANNEL_RGB_INITIALIZER(0x30, 0x30, 0x30); uint32_t ul = CHANNEL_RGB_INITIALIZER(0x30, 0x30, 0x30);
uint32_t lr = CHANNEL_RGB_INITIALIZER(0x80, 0x80, 0x80); uint32_t lr = CHANNEL_RGB_INITIALIZER(0x80, 0x80, 0x80);
ncplane_stain(n, y, 66, ul, lr, ul, lr); ncplane_stain(n, y - 1, 65, ul, lr, ul, lr);
// the vertical eighths // the vertical eighths
ncplane_cursor_move_yx(n, y - 2, 2); ncplane_cursor_move_yx(n, y - 2, 2);
ul = CHANNEL_RGB_INITIALIZER(0x60, 0x7d, 0x3b); ul = CHANNEL_RGB_INITIALIZER(0x60, 0x7d, 0x3b);

@ -1124,7 +1124,7 @@ int ncvisual_blit(struct ncvisual* ncv, int rows, int cols,
void nclog(const char* fmt, ...); void nclog(const char* fmt, ...);
bool is_linux_console(int fd, unsigned no_font_changes); bool is_linux_console(int fd, unsigned no_font_changes, bool* quadrants);
// logging // logging
extern int loglevel; extern int loglevel;

@ -213,7 +213,8 @@ program_line_drawing_chars(int fd, struct unimapdesc* map){
static int static int
program_block_drawing_chars(int fd, struct console_font_op* cfo, program_block_drawing_chars(int fd, struct console_font_op* cfo,
struct unimapdesc* map){ struct unimapdesc* map, unsigned no_font_changes,
bool* quadrants){
struct shimmer { struct shimmer {
unsigned qbits; unsigned qbits;
wchar_t w; wchar_t w;
@ -243,12 +244,14 @@ program_block_drawing_chars(int fd, struct console_font_op* cfo,
{ .qbits = 1, .w = L'', .found = false, }, { .qbits = 1, .w = L'', .found = false, },
}; };
// first, take a pass to see which glyphs we already have // first, take a pass to see which glyphs we already have
size_t numfound = 0;
for(unsigned i = 0 ; i < cfo->charcount ; ++i){ for(unsigned i = 0 ; i < cfo->charcount ; ++i){
if(map->entries[i].unicode >= 0x2580 && map->entries[i].unicode <= 0x259f){ if(map->entries[i].unicode >= 0x2580 && map->entries[i].unicode <= 0x259f){
for(size_t s = 0 ; s < sizeof(shimmers) / sizeof(*shimmers) ; ++s){ for(size_t s = 0 ; s < sizeof(shimmers) / sizeof(*shimmers) ; ++s){
if(map->entries[i].unicode == shimmers[s].w){ if(map->entries[i].unicode == shimmers[s].w){
logdebug("Found %lc at fontidx %u\n", shimmers[s].w, i); logdebug("Found %lc at fontidx %u\n", shimmers[s].w, i);
shimmers[s].found = true; shimmers[s].found = true;
++numfound;
break; break;
} }
} }
@ -256,11 +259,21 @@ program_block_drawing_chars(int fd, struct console_font_op* cfo,
if(map->entries[i].unicode == eighths[s].w){ if(map->entries[i].unicode == eighths[s].w){
logdebug("Found %lc at fontidx %u\n", eighths[s].w, i); logdebug("Found %lc at fontidx %u\n", eighths[s].w, i);
eighths[s].found = true; eighths[s].found = true;
++numfound;
break; break;
} }
} }
} }
} }
if(numfound == (sizeof(shimmers) + sizeof(eighths)) / sizeof(*shimmers)){
logdebug("All %zu desired glyphs were already present\n", numfound);
*quadrants = true;
return 0;
}
if(no_font_changes){
logdebug("Not reprogramming kernel font, per orders\n");
return 0;
}
int added = 0; int added = 0;
unsigned candidate = cfo->charcount; unsigned candidate = cfo->charcount;
for(size_t s = 0 ; s < sizeof(shimmers) / sizeof(*shimmers) ; ++s){ for(size_t s = 0 ; s < sizeof(shimmers) / sizeof(*shimmers) ; ++s){
@ -314,13 +327,17 @@ program_block_drawing_chars(int fd, struct console_font_op* cfo,
logwarn("Error setting kernel unicode map (%s)\n", strerror(errno)); logwarn("Error setting kernel unicode map (%s)\n", strerror(errno));
return -1; return -1;
} }
if(added + numfound == (sizeof(shimmers) + sizeof(eighths)) / sizeof(*shimmers)){
*quadrants = true;
}
loginfo("Successfully added %d kernel font glyph%s\n", added, added == 1 ? "" : "s"); loginfo("Successfully added %d kernel font glyph%s\n", added, added == 1 ? "" : "s");
return 0; return 0;
} }
static int static int
reprogram_linux_font(int fd, struct console_font_op* cfo, reprogram_linux_font(int fd, struct console_font_op* cfo,
struct unimapdesc* map){ struct unimapdesc* map, unsigned no_font_changes,
bool* quadrants){
if(ioctl(fd, KDFONTOP, cfo)){ if(ioctl(fd, KDFONTOP, cfo)){
logwarn("Error reading Linux kernelfont (%s)\n", strerror(errno)); logwarn("Error reading Linux kernelfont (%s)\n", strerror(errno));
return -1; return -1;
@ -338,17 +355,19 @@ reprogram_linux_font(int fd, struct console_font_op* cfo,
loginfo("Kernel Unimap size: %hu/%hu\n", map->entry_ct, USHRT_MAX); loginfo("Kernel Unimap size: %hu/%hu\n", map->entry_ct, USHRT_MAX);
// for certain sets of characters, we're not going to draw them in, but we // for certain sets of characters, we're not going to draw them in, but we
// do want to ensure they map to something plausible... // do want to ensure they map to something plausible...
if(program_line_drawing_chars(fd, map)){ if(!no_font_changes){
return -1; if(program_line_drawing_chars(fd, map)){
return -1;
}
} }
if(program_block_drawing_chars(fd, cfo, map)){ if(program_block_drawing_chars(fd, cfo, map, no_font_changes, quadrants)){
return -1; return -1;
} }
return 0; return 0;
} }
static int static int
reprogram_console_font(int fd){ reprogram_console_font(int fd, unsigned no_font_changes, bool* quadrants){
struct console_font_op cfo = { struct console_font_op cfo = {
.op = KD_FONT_OP_GET, .op = KD_FONT_OP_GET,
.charcount = 512, .charcount = 512,
@ -370,14 +389,16 @@ reprogram_console_font(int fd){
free(cfo.data); free(cfo.data);
return -1; return -1;
} }
int r = reprogram_linux_font(fd, &cfo, &map); int r = reprogram_linux_font(fd, &cfo, &map, no_font_changes, quadrants);
free(cfo.data); free(cfo.data);
free(map.entries); free(map.entries);
return r; return r;
} }
// is the provided fd a Linux console? // is the provided fd a Linux console? if so, returns true. if it is indeed
bool is_linux_console(int fd, unsigned no_font_changes){ // a Linux console, and the console font has the quadrant glyphs (either
// because they were already present, or we added them), quadrants is set high.
bool is_linux_console(int fd, unsigned no_font_changes, bool* quadrants){
if(fd < 0){ if(fd < 0){
return false; return false;
} }
@ -387,11 +408,7 @@ bool is_linux_console(int fd, unsigned no_font_changes){
return false; return false;
} }
loginfo("Verified Linux console, mode %d\n", mode); loginfo("Verified Linux console, mode %d\n", mode);
if(no_font_changes){ reprogram_console_font(fd, no_font_changes, quadrants);
logdebug("Not reprogramming the console font due to option\n");
return true;
}
reprogram_console_font(fd);
return true; return true;
} }
#else #else

@ -267,6 +267,9 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd,
ti->caps.quadrants = true; ti->caps.quadrants = true;
// ti->caps.sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */ // ti->caps.sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */
ti->caps.rgb = true; ti->caps.rgb = true;
if(add_smulx_escapes(ti, tablelen, tableused)){
return -1;
}
}else if(qterm == TERMINAL_VTE){ }else if(qterm == TERMINAL_VTE){
termname = "VTE"; termname = "VTE";
ti->caps.quadrants = true; ti->caps.quadrants = true;
@ -287,9 +290,7 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd,
termname = "WezTerm"; termname = "WezTerm";
ti->caps.rgb = true; ti->caps.rgb = true;
ti->caps.quadrants = true; ti->caps.quadrants = true;
// FIXME get version from query if(ti->termversion && strcmp(ti->termversion, "20210610") >= 0){
const char* termver = getenv("TERM_PROGRAM_VERSION");
if(termver && strcmp(termver, "20210610") >= 0){
ti->caps.sextants = true; // good caps.sextants as of 2021-06-10 ti->caps.sextants = true; // good caps.sextants as of 2021-06-10
if(add_smulx_escapes(ti, tablelen, tableused)){ if(add_smulx_escapes(ti, tablelen, tableused)){
return -1; return -1;
@ -309,11 +310,7 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd,
ti->termversion = strdup(un.release); ti->termversion = strdup(un.release);
} }
termname = "Linux console"; termname = "Linux console";
// FIXME get kernel version
ti->caps.braille = false; // no caps.braille, no caps.sextants in linux console ti->caps.braille = false; // no caps.braille, no caps.sextants in linux console
// FIXME if the NCOPTION_NO_FONT_CHANGES, this isn't true
// FIXME we probably want to ID based off ioctl()s in linux.c
ti->caps.quadrants = true; // we program caps.quadrants on the console
} }
// run a wcwidth(⣿) to guarantee libc Unicode 3 support, independent of term // run a wcwidth(⣿) to guarantee libc Unicode 3 support, independent of term
if(wcwidth(L'') < 0){ if(wcwidth(L'') < 0){
@ -340,7 +337,8 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
int* cursor_y, int* cursor_x){ int* cursor_y, int* cursor_x){
queried_terminals_e qterm = TERMINAL_UNKNOWN; queried_terminals_e qterm = TERMINAL_UNKNOWN;
memset(ti, 0, sizeof(*ti)); memset(ti, 0, sizeof(*ti));
if(is_linux_console(fd, nonewfonts)){ // we might or might not program quadrants into the console font
if(is_linux_console(fd, nonewfonts, &ti->caps.quadrants)){
qterm = TERMINAL_LINUX; qterm = TERMINAL_LINUX;
} }
if(fd >= 0){ if(fd >= 0){
@ -476,6 +474,7 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
{ NCSTYLE_ITALIC, ESCAPE_SITM, "sitm", A_ITALIC }, { NCSTYLE_ITALIC, ESCAPE_SITM, "sitm", A_ITALIC },
{ NCSTYLE_STRUCK, ESCAPE_SMXX, "smxx", 0 }, { NCSTYLE_STRUCK, ESCAPE_SMXX, "smxx", 0 },
{ NCSTYLE_BLINK, ESCAPE_BLINK, "blink", A_BLINK }, { NCSTYLE_BLINK, ESCAPE_BLINK, "blink", A_BLINK },
{ NCSTYLE_UNDERCURL, ESCAPE_SMULX, "smulx", 0 },
{ 0, 0, NULL, 0 } { 0, 0, NULL, 0 }
}; };
int nocolor_stylemask = tigetnum("ncv"); int nocolor_stylemask = tigetnum("ncv");

Loading…
Cancel
Save