[linux] blit fb copy back after font change

After reprogramming the Linux console font, remap
the framebuffer. Verify that the size and geometry
match the copy we made beforehand, and assuming
they do, blit the copy back into the framebuffer.
This allows us to reprogram the console font while
maintaining any graphics present. Closes #2108.
This commit is contained in:
nick black 2021-08-29 20:55:45 -04:00 committed by nick black
parent 6a6b9ad3b8
commit 22386f3154
2 changed files with 27 additions and 16 deletions

View File

@ -417,8 +417,8 @@ program_line_drawing_chars(int fd, struct unimapdesc* map){
// we have to keep a copy of the linux framebuffer while we reprogram fonts
struct framebuffer_copy {
void* map;
size_t mapsize;
int pixely, pixelx;
size_t maplen;
unsigned pixely, pixelx;
};
// build |fbdup| from the framebuffer owned by ti, which will be closed. this
@ -429,18 +429,20 @@ copy_and_close_linux_fb(tinfo* ti, struct framebuffer_copy* fbdup){
return -1;
}
munmap(ti->linux_fbuffer, ti->linux_fb_len);
fbdup->mapsize = ti->linux_fb_len;
fbdup->maplen = ti->linux_fb_len;
ti->linux_fbuffer = NULL;
ti->linux_fb_len = 0;
close(ti->linux_fb_fd);
ti->linux_fb_fd = -1;
// FIXME need pixelx/pixely!
// FIXME can we get away without the fd close?
//close(ti->linux_fb_fd);
//ti->linux_fb_fd = -1;
fbdup->pixely = ti->pixy;
fbdup->pixelx = ti->pixx;
return 0;
}
static void
kill_fbcopy(struct framebuffer_copy* fbdup){
munmap(fbdup->map, fbdup->mapsize);
free(fbdup->map);
}
static int
@ -610,8 +612,6 @@ program_block_drawing_chars(tinfo* ti, int fd, struct console_font_op* cfo,
kill_fbcopy(&fbdup);
return -1;
}
// FIXME reopen framebuffer, and blit it
kill_fbcopy(&fbdup);
if(halvesadded + halvesfound == sizeof(half) / sizeof(*half)){
*halfblocks = true;
}
@ -620,6 +620,17 @@ program_block_drawing_chars(tinfo* ti, int fd, struct console_font_op* cfo,
}
added += halvesadded;
loginfo("successfully added %d kernel font glyph%s\n", added, added == 1 ? "" : "s");
unsigned pixely, pixelx;
if(get_linux_fb_pixelgeom(ti, &pixely, &pixelx)){
kill_fbcopy(&fbdup);
return -1;
}
if(pixely != fbdup.pixely || pixelx != fbdup.pixelx || ti->linux_fb_len != fbdup.maplen){
logwarn("framebuffer changed size, not reblitting\n");
}else{
memcpy(ti->linux_fbuffer, fbdup.map, fbdup.maplen);
}
kill_fbcopy(&fbdup);
return 0;
}
@ -754,7 +765,7 @@ bool is_linux_framebuffer(tinfo* ti){
ti->linux_fb_fd = -1;
return false;
}
if(get_linux_fb_pixelgeom(ti, NULL, NULL)){
if(get_linux_fb_pixelgeom(ti, &ti->pixy, &ti->pixx)){
close(fd);
ti->linux_fb_fd = -1;
free(ti->linux_fb_dev);

View File

@ -582,18 +582,18 @@ apply_term_heuristics(tinfo* ti, const char* termname, queried_terminals_e qterm
if(uname(&un) == 0){
ti->termversion = strdup(un.release);
}
ti->caps.halfblocks = false;
ti->caps.braille = false; // no caps.braille, no caps.sextants in linux console
if(ti->ttyfd >= 0){
reprogram_console_font(ti, nonewfonts, &ti->caps.halfblocks,
&ti->caps.quadrants);
}
if(is_linux_framebuffer(ti)){
termname = "Linux framebuffer";
setup_fbcon_bitmaps(ti, ti->linux_fb_fd);
}else{
termname = "Linux console";
}
ti->caps.halfblocks = false;
ti->caps.braille = false; // no caps.braille, no caps.sextants in linux console
if(ti->ttyfd >= 0){
reprogram_console_font(ti, nonewfonts, &ti->caps.halfblocks,
&ti->caps.quadrants);
}
// assume no useful unicode drawing unless we're positively sure
#else
(void)nonewfonts;