Take the console into graphics mode while drawing

This commit is contained in:
flamingcow
2026-07-25 21:30:37 -07:00
parent 892e855207
commit 12958ced56
+31
View File
@@ -12,6 +12,11 @@ const (
fbioGetVScreenInfo = 0x4600
fbioBlank = 0x4611
fbBlankUnblank = 0
kdSetMode = 0x4b3a
kdText = 0x00
kdGraphics = 0x01
consolePath = "/dev/tty0"
)
// The variable screen info is a flat run of 40 u32s, so it is read as an array
@@ -28,6 +33,7 @@ const (
type framebuffer struct {
file *os.File
tty *os.File
mem []byte
back []byte
w int
@@ -38,6 +44,22 @@ type framebuffer struct {
bShift uint
}
// The kernel console draws into the same framebuffer, including a blinking
// cursor and any keyboard echo, which fights every frame we write. Putting the
// active console into graphics mode stops it touching the framebuffer at all.
func takeConsole() (*os.File, error) {
tty, err := os.OpenFile(consolePath, os.O_RDWR, 0)
if err != nil {
return nil, err
}
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, tty.Fd(),
kdSetMode, kdGraphics); errno != 0 {
tty.Close()
return nil, fmt.Errorf("console to graphics mode: %w", errno)
}
return tty, nil
}
func openFramebuffer(path string) (*framebuffer, error) {
f, err := os.OpenFile(path, os.O_RDWR, 0)
if err != nil {
@@ -81,12 +103,21 @@ func openFramebuffer(path string) (*framebuffer, error) {
return nil, fmt.Errorf("mmap: %w", err)
}
fb.back = make([]byte, fb.stride*fb.h)
fb.tty, err = takeConsole()
if err != nil {
unix.Munmap(fb.mem)
f.Close()
return nil, err
}
return fb, nil
}
func (fb *framebuffer) close() {
fb.fill(rgb{})
fb.flush()
unix.Syscall(unix.SYS_IOCTL, fb.tty.Fd(), kdSetMode, kdText)
fb.tty.Close()
unix.Munmap(fb.mem)
fb.file.Close()
}