From 8fe8e35efef1487073a7d61e5abc00fed2da78c0 Mon Sep 17 00:00:00 2001 From: nick black Date: Sat, 26 Jun 2021 03:43:31 -0400 Subject: [PATCH] set quadrants for linux console only if we reprogrammed the font, or found them --- src/info/main.c | 14 ++++---------- src/lib/internal.h | 2 +- src/lib/linux.c | 45 +++++++++++++++++++++++++++++++-------------- src/lib/termdesc.c | 15 +++++++-------- 4 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/info/main.c b/src/info/main.c index 7b30efee3..07700d931 100644 --- a/src/info/main.c +++ b/src/info/main.c @@ -37,12 +37,6 @@ braille_viz(ncplane* n, const char* l, const wchar_t* egcs, const char* r, const static int unicodedumper(struct ncplane* n, tinfo* ti, const char* indent){ 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", NCHALFBLOCKS, NCQUADBLOCKS, NCSEXBLOCKS); ncplane_printf(n, " ⎩%ls⎭ ⎪🮋▏⎪ 🯲🯳\n", @@ -65,17 +59,17 @@ unicodedumper(struct ncplane* n, tinfo* ti, const char* indent){ ncplane_printf(n, "⎪🮇▊⎪\n"); braille_viz(n, "⎣",NCBRAILLEEGCS + 192, "⎦", indent); ncplane_printf(n, "⎪▕▉⎪\n"); - ncplane_printf(n, "%s⎛%ls⎞ ▔🭶🭷🭸🭹🭺🭻▁ 🭁 🭂 🭃 🭄 🭅 🭆 🭑 🭐 🭏 🭎 🭍 🭌 🭆🭑 🭄🭏 🭅🭐 🭃🭎 🭂🭍 🭁🭌 🭨🭪 ⎩ █⎭\n", + ncplane_printf(n, "%s⎛%ls⎞ ▔🭶🭷🭸🭹🭺🭻▁ 🭁 🭂 🭃 🭄 🭅 🭆 🭑 🭐 🭏 🭎 🭍 🭌 🭆🭑 🭄🭏 🭅🭐 🭃🭎 🭂🭍 🭁🭌 🭨🭪 ⎩ █⎭\n", indent, NCEIGHTHSBOTTOM); - ncplane_printf(n, "%s⎝%ls⎠ ▏🭰🭱🭲🭳🭴🭵▕ 🭒 🭓 🭔 🭕 🭖 🭧 🭜 🭟 🭠 🭡 🭞 🭝 🭧🭜 🭕🭠 🭖🭡 🭔🭟 🭓🭞 🭒🭝 🭪🭨 \n", + ncplane_printf(n, "%s⎝%ls⎠ ▏🭰🭱🭲🭳🭴🭵▕ 🭒 🭓 🭔 🭕 🭖 🭧 🭜 🭟 🭠 🭡 🭞 🭝 🭧🭜 🭕🭠 🭖🭡 🭔🭟 🭓🭞 🭒🭝 🭪🭨 \n", indent, NCEIGHTSTOP); int y, x; ncplane_cursor_yx(n, &y, &x); // 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 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 ncplane_cursor_move_yx(n, y - 2, 2); ul = CHANNEL_RGB_INITIALIZER(0x60, 0x7d, 0x3b); diff --git a/src/lib/internal.h b/src/lib/internal.h index 2f1272594..36a6411f1 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -1124,7 +1124,7 @@ int ncvisual_blit(struct ncvisual* ncv, int rows, int cols, 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 extern int loglevel; diff --git a/src/lib/linux.c b/src/lib/linux.c index 6ff2c977a..1a1c9d756 100644 --- a/src/lib/linux.c +++ b/src/lib/linux.c @@ -213,7 +213,8 @@ program_line_drawing_chars(int fd, struct unimapdesc* map){ static int 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 { unsigned qbits; wchar_t w; @@ -243,12 +244,14 @@ program_block_drawing_chars(int fd, struct console_font_op* cfo, { .qbits = 1, .w = L'▁', .found = false, }, }; // first, take a pass to see which glyphs we already have + size_t numfound = 0; for(unsigned i = 0 ; i < cfo->charcount ; ++i){ if(map->entries[i].unicode >= 0x2580 && map->entries[i].unicode <= 0x259f){ for(size_t s = 0 ; s < sizeof(shimmers) / sizeof(*shimmers) ; ++s){ if(map->entries[i].unicode == shimmers[s].w){ logdebug("Found %lc at fontidx %u\n", shimmers[s].w, i); shimmers[s].found = true; + ++numfound; break; } } @@ -256,11 +259,21 @@ program_block_drawing_chars(int fd, struct console_font_op* cfo, if(map->entries[i].unicode == eighths[s].w){ logdebug("Found %lc at fontidx %u\n", eighths[s].w, i); eighths[s].found = true; + ++numfound; 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; unsigned candidate = cfo->charcount; 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)); 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"); return 0; } static int 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)){ logwarn("Error reading Linux kernelfont (%s)\n", strerror(errno)); 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); // for certain sets of characters, we're not going to draw them in, but we // do want to ensure they map to something plausible... - if(program_line_drawing_chars(fd, map)){ - return -1; + if(!no_font_changes){ + 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 0; } static int -reprogram_console_font(int fd){ +reprogram_console_font(int fd, unsigned no_font_changes, bool* quadrants){ struct console_font_op cfo = { .op = KD_FONT_OP_GET, .charcount = 512, @@ -370,14 +389,16 @@ reprogram_console_font(int fd){ free(cfo.data); 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(map.entries); return r; } -// is the provided fd a Linux console? -bool is_linux_console(int fd, unsigned no_font_changes){ +// is the provided fd a Linux console? if so, returns true. if it is indeed +// 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){ return false; } @@ -387,11 +408,7 @@ bool is_linux_console(int fd, unsigned no_font_changes){ return false; } loginfo("Verified Linux console, mode %d\n", mode); - if(no_font_changes){ - logdebug("Not reprogramming the console font due to option\n"); - return true; - } - reprogram_console_font(fd); + reprogram_console_font(fd, no_font_changes, quadrants); return true; } #else diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 431d5816c..387cde437 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -267,6 +267,9 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd, ti->caps.quadrants = true; // ti->caps.sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */ ti->caps.rgb = true; + if(add_smulx_escapes(ti, tablelen, tableused)){ + return -1; + } }else if(qterm == TERMINAL_VTE){ termname = "VTE"; ti->caps.quadrants = true; @@ -287,9 +290,7 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd, termname = "WezTerm"; ti->caps.rgb = true; ti->caps.quadrants = true; - // FIXME get version from query - const char* termver = getenv("TERM_PROGRAM_VERSION"); - if(termver && strcmp(termver, "20210610") >= 0){ + if(ti->termversion && strcmp(ti->termversion, "20210610") >= 0){ ti->caps.sextants = true; // good caps.sextants as of 2021-06-10 if(add_smulx_escapes(ti, tablelen, tableused)){ return -1; @@ -309,11 +310,7 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd, ti->termversion = strdup(un.release); } termname = "Linux console"; - // FIXME get kernel version 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 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){ queried_terminals_e qterm = TERMINAL_UNKNOWN; 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; } 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_STRUCK, ESCAPE_SMXX, "smxx", 0 }, { NCSTYLE_BLINK, ESCAPE_BLINK, "blink", A_BLINK }, + { NCSTYLE_UNDERCURL, ESCAPE_SMULX, "smulx", 0 }, { 0, 0, NULL, 0 } }; int nocolor_stylemask = tigetnum("ncv");