detect drawable linux framebuffer #1369

pull/1859/head
nick black 3 years ago
parent dce4426dcf
commit 2895615e06
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -1123,8 +1123,6 @@ 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* quadrants);
// logging
extern int loglevel;

@ -1,6 +1,11 @@
#include "linux.h"
#include "internal.h"
#ifdef __linux__
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <sys/ioctl.h>
@ -411,6 +416,26 @@ bool is_linux_console(int fd, unsigned no_font_changes, bool* quadrants){
reprogram_console_font(fd, no_font_changes, quadrants);
return true;
}
bool is_linux_framebuffer(tinfo* ti){
// FIXME there might be multiple framebuffers present; how do we determine
// which one is ours?
const char* dev = "/dev/fb0";
int fd = open(dev, O_RDWR | O_CLOEXEC);
if(fd < 0){
logdebug("Couldn't open framebuffer device %s\n", dev);
return false;
}
struct fb_var_screeninfo fbi = {};
if(ioctl(fd, FBIOGET_VSCREENINFO, &fbi)){
logdebug("Couldn't get framebuffer info from %s (%s?)\n", dev, strerror(errno));
close(fd);
return false;
}
loginfo("Linux framebuffer detected at %s: %dx%d\n", dev, fbi.yres, fbi.xres);
ti->linux_fb_fd = fd;
return true;
}
#else
bool is_linux_console(int fd, unsigned no_font_changes, bool* quadrants){
(void)fd;
@ -418,4 +443,9 @@ bool is_linux_console(int fd, unsigned no_font_changes, bool* quadrants){
(void)quadrants;
return false;
}
bool is_linux_framebuffer(tinfo* ti){
(void)ti;
return false;
}
#endif

@ -0,0 +1,22 @@
#ifndef NOTCURSES_LINUX
#define NOTCURSES_LINUX
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
struct tinfo;
bool is_linux_console(int fd, unsigned no_font_changes, bool* quadrants);
// if is_linux_console returned true, call this to determine whether it is
// a drawable framebuffer console. do not call if not is_linux_console!
bool is_linux_framebuffer(struct tinfo* ti);
#ifdef __cplusplus
}
#endif
#endif

@ -5,6 +5,7 @@
#include <sys/utsname.h>
#include "internal.h"
#include "input.h"
#include "linux.h"
// there does not exist any true standard terminal size. with that said, we
// need assume *something* for the case where we're not actually attached to
@ -155,6 +156,9 @@ void free_terminfo_cache(tinfo* ti){
ncinputlayer_stop(&ti->input);
free(ti->termversion);
free(ti->esctable);
if(ti->linux_fb_fd >= 0){
close(ti->linux_fb_fd);
}
}
// compare one terminal version against another. numerics, separated by
@ -416,7 +420,11 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd,
if(uname(&un) == 0){
ti->termversion = strdup(un.release);
}
termname = "Linux console";
if(ti->linux_fb_fd >= 0){
termname = "Linux framebuffer";
}else{
termname = "Linux console";
}
ti->caps.braille = false; // no caps.braille, no caps.sextants in linux console
}
// run a wcwidth(⣿) to guarantee libc Unicode 3 support, independent of term
@ -478,9 +486,13 @@ 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));
ti->linux_fb_fd = -1;
// we might or might not program quadrants into the console font
if(is_linux_console(fd, nonewfonts, &ti->caps.quadrants)){
qterm = TERMINAL_LINUX;
if(is_linux_framebuffer(ti)){
// FIXME set up pixel-drawing API for framebuffer #1369
}
}
if(fd >= 0){
if(qterm == TERMINAL_UNKNOWN){

@ -159,6 +159,8 @@ typedef struct tinfo {
int default_rows; // LINES environment var / lines terminfo / 24
int default_cols; // COLUMNS environment var / cols terminfo / 80
int linux_fb_fd; // linux framebuffer device fd
} tinfo;
// retrieve the terminfo(5)-style escape 'e' from tdesc (NULL if undefined).

Loading…
Cancel
Save