mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
linux console: shim in half blocks #201
This commit is contained in:
parent
a009eb946c
commit
eaa1c28756
@ -814,7 +814,7 @@ int get_controlling_tty(void);
|
||||
if((nc)->loglevel >= NCLOGLEVEL_ERROR){ \
|
||||
nclog("%s:%d:" fmt, __func__, __LINE__, ##__VA_ARGS__); } }while(0);
|
||||
|
||||
#define logwarning(nc, fmt, ...) do{ \
|
||||
#define logwarn(nc, fmt, ...) do{ \
|
||||
if((nc)->loglevel >= NCLOGLEVEL_WARNING){ \
|
||||
nclog("%s:%d:" fmt, __func__, __LINE__, ##__VA_ARGS__); } }while(0);
|
||||
|
||||
|
@ -129,6 +129,21 @@ shim_lower_right_quad(struct consolefontdesc* cfd, unsigned idx){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add UCS2 codepoint |w| to |map| for font idx |fidx|
|
||||
static int
|
||||
add_to_map(const notcurses* nc, struct unimapdesc* map, wchar_t w, unsigned fidx){
|
||||
logdebug(nc, "Adding mapping U+%04x -> %03u\n", w, fidx);
|
||||
struct unipair* tmp = realloc(map->entries, sizeof(*map->entries) * (map->entry_ct + 1));
|
||||
if(tmp == NULL){
|
||||
return -1;
|
||||
}
|
||||
map->entries = tmp;
|
||||
map->entries[map->entry_ct].unicode = w;
|
||||
map->entries[map->entry_ct].fontpos = fidx;
|
||||
++map->entry_ct;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
program_line_drawing_chars(const notcurses* nc, struct unimapdesc* map){
|
||||
struct simset {
|
||||
@ -185,27 +200,21 @@ program_line_drawing_chars(const notcurses* nc, struct unimapdesc* map){
|
||||
if(fontidx > -1){
|
||||
for(size_t widx = 0 ; widx < wcslen(s->ws) ; ++widx){
|
||||
if(!found[widx]){
|
||||
logdebug(nc, "Adding mapping U+%04x -> %03u\n", s->ws[widx], fontidx);
|
||||
struct unipair* tmp = realloc(map->entries, sizeof(*map->entries) * (map->entry_ct + 1));
|
||||
if(tmp == NULL){
|
||||
if(add_to_map(nc, map, s->ws[widx], fontidx)){
|
||||
return -1;
|
||||
}
|
||||
map->entries = tmp;
|
||||
map->entries[map->entry_ct].unicode = s->ws[widx];
|
||||
map->entries[map->entry_ct].fontpos = fontidx;
|
||||
++map->entry_ct;
|
||||
++toadd;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
logwarning(nc, "Couldn't find any glyphs for set %zu\n", sidx);
|
||||
logwarn(nc, "Couldn't find any glyphs for set %zu\n", sidx);
|
||||
}
|
||||
}
|
||||
if(toadd == 0){
|
||||
return 0;
|
||||
}
|
||||
if(ioctl(nc->ttyfd, PIO_UNIMAP, map)){
|
||||
logwarning(nc, "Error setting kernel unicode map (%s)\n", strerror(errno));
|
||||
logwarn(nc, "Error setting kernel unicode map (%s)\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
loginfo(nc, "Successfully added %d kernel unicode mapping%s\n",
|
||||
@ -219,18 +228,59 @@ program_block_drawing_chars(const notcurses* nc, struct consolefontdesc* cfd,
|
||||
struct shimmer {
|
||||
int (*glyphfxn)(struct consolefontdesc* cfd, unsigned idx);
|
||||
wchar_t w;
|
||||
bool found;
|
||||
} shimmers[] = {
|
||||
{ .glyphfxn = shim_upper_half_block, .w = L'▀', },
|
||||
{ .glyphfxn = shim_lower_half_block, .w = L'▄', },
|
||||
{ .glyphfxn = shim_left_half_block, .w = L'▌', },
|
||||
{ .glyphfxn = shim_right_half_block, .w = L'▐', },
|
||||
{ .glyphfxn = shim_upper_half_block, .w = L'▀', .found = false, },
|
||||
{ .glyphfxn = shim_lower_half_block, .w = L'▄', .found = false, },
|
||||
{ .glyphfxn = shim_left_half_block, .w = L'▌', .found = false, },
|
||||
{ .glyphfxn = shim_right_half_block, .w = L'▐', .found = false, },
|
||||
// FIXME more
|
||||
};
|
||||
int toadd = 0;
|
||||
|
||||
// FIXME need a table of functions + UCS2
|
||||
// first, take a pass to see which glyphs we already have
|
||||
for(unsigned i = 0 ; i < cfd->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(nc, "Found %lc at fontidx %u\n", shimmers[s].w, i);
|
||||
shimmers[s].found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int added = 0;
|
||||
unsigned candidate = cfd->charcount;
|
||||
for(size_t s = 0 ; s < sizeof(shimmers) / sizeof(*shimmers) ; ++s){
|
||||
if(!shimmers[s].found){
|
||||
while(--candidate){
|
||||
if(map->entries[candidate].unicode < 0x2580 || map->entries[candidate].unicode > 0x259f){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(candidate == 0){
|
||||
logwarn(nc, "Ran out of replaceable glyphs for U+%04x\n", shimmers[s].w);
|
||||
return -1;
|
||||
}
|
||||
if(shimmers[s].glyphfxn(cfd, candidate)){
|
||||
logwarn(nc, "Error replacing glyph for U+%04x at %u\n", shimmers[s].w, candidate);
|
||||
return -1;
|
||||
}
|
||||
if(add_to_map(nc, map, shimmers[s].w, candidate)){
|
||||
return -1;
|
||||
}
|
||||
++added;
|
||||
}
|
||||
}
|
||||
if(ioctl(nc->ttyfd, PIO_FONTX, cfd)){
|
||||
logwarn(nc, "Error programming kernel font (%s)\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(ioctl(nc->ttyfd, PIO_UNIMAP, map)){
|
||||
logwarn(nc, "Error setting kernel unicode map (%s)\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
loginfo(nc, "Successfully added %d kernel font glyph%s\n",
|
||||
toadd, toadd == 1 ? "" : "s");
|
||||
added, added == 1 ? "" : "s");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -238,17 +288,17 @@ static int
|
||||
reprogram_linux_font(const notcurses* nc, struct consolefontdesc* cfd,
|
||||
struct unimapdesc* map){
|
||||
if(ioctl(nc->ttyfd, GIO_FONTX, cfd)){
|
||||
logwarning(nc, "Error reading Linux kernelfont (%s)\n", strerror(errno));
|
||||
logwarn(nc, "Error reading Linux kernelfont (%s)\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
loginfo(nc, "Kernel font size (glyphcount): %hu\n", cfd->charcount);
|
||||
loginfo(nc, "Kernel font character geometry: 8x%hu\n", cfd->charheight);
|
||||
if(cfd->charcount > 512){
|
||||
logwarning(nc, "Warning: kernel returned excess charcount\n");
|
||||
logwarn(nc, "Warning: kernel returned excess charcount\n");
|
||||
return -1;
|
||||
}
|
||||
if(ioctl(nc->ttyfd, GIO_UNIMAP, map)){
|
||||
logwarning(nc, "Error reading Linux unimap (%s)\n", strerror(errno));
|
||||
logwarn(nc, "Error reading Linux unimap (%s)\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
loginfo(nc, "Kernel Unimap size: %hu/%hu\n", map->entry_ct, USHRT_MAX);
|
||||
@ -270,7 +320,7 @@ reprogram_console_font(const notcurses* nc){
|
||||
size_t totsize = 32 * cfd.charcount;
|
||||
cfd.chardata = malloc(totsize);
|
||||
if(cfd.chardata == NULL){
|
||||
logwarning(nc, "Error acquiring %zub for font descriptors (%s)\n", totsize, strerror(errno));
|
||||
logwarn(nc, "Error acquiring %zub for font descriptors (%s)\n", totsize, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
struct unimapdesc map = {};
|
||||
@ -278,7 +328,7 @@ reprogram_console_font(const notcurses* nc){
|
||||
totsize = map.entry_ct * sizeof(struct unipair);
|
||||
map.entries = malloc(totsize);
|
||||
if(map.entries == NULL){
|
||||
logwarning(nc, "Error acquiring %zub for Unicode font map (%s)\n", totsize, strerror(errno));
|
||||
logwarn(nc, "Error acquiring %zub for Unicode font map (%s)\n", totsize, strerror(errno));
|
||||
free(cfd.chardata);
|
||||
return -1;
|
||||
}
|
||||
|
@ -735,7 +735,7 @@ get_tty_fd(notcurses* nc, FILE* ttyfp){
|
||||
int fd = -1;
|
||||
if(ttyfp){
|
||||
if((fd = fileno(ttyfp)) < 0){
|
||||
logwarning(nc, "No file descriptor was available in outfp %p\n", ttyfp);
|
||||
logwarn(nc, "No file descriptor was available in outfp %p\n", ttyfp);
|
||||
}else{
|
||||
if(isatty(fd)){
|
||||
fd = dup(fd);
|
||||
@ -748,7 +748,7 @@ get_tty_fd(notcurses* nc, FILE* ttyfp){
|
||||
if(fd < 0){
|
||||
fd = open("/dev/tty", O_RDWR | O_CLOEXEC);
|
||||
if(fd < 0){
|
||||
logwarning(nc, "Error opening /dev/tty (%s)\n", strerror(errno));
|
||||
logwarn(nc, "Error opening /dev/tty (%s)\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
|
Loading…
x
Reference in New Issue
Block a user