Take the console into graphics mode while drawing
This commit is contained in:
@@ -12,6 +12,11 @@ const (
|
|||||||
fbioGetVScreenInfo = 0x4600
|
fbioGetVScreenInfo = 0x4600
|
||||||
fbioBlank = 0x4611
|
fbioBlank = 0x4611
|
||||||
fbBlankUnblank = 0
|
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
|
// 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 {
|
type framebuffer struct {
|
||||||
file *os.File
|
file *os.File
|
||||||
|
tty *os.File
|
||||||
mem []byte
|
mem []byte
|
||||||
back []byte
|
back []byte
|
||||||
w int
|
w int
|
||||||
@@ -38,6 +44,22 @@ type framebuffer struct {
|
|||||||
bShift uint
|
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) {
|
func openFramebuffer(path string) (*framebuffer, error) {
|
||||||
f, err := os.OpenFile(path, os.O_RDWR, 0)
|
f, err := os.OpenFile(path, os.O_RDWR, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -81,12 +103,21 @@ func openFramebuffer(path string) (*framebuffer, error) {
|
|||||||
return nil, fmt.Errorf("mmap: %w", err)
|
return nil, fmt.Errorf("mmap: %w", err)
|
||||||
}
|
}
|
||||||
fb.back = make([]byte, fb.stride*fb.h)
|
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
|
return fb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fb *framebuffer) close() {
|
func (fb *framebuffer) close() {
|
||||||
fb.fill(rgb{})
|
fb.fill(rgb{})
|
||||||
fb.flush()
|
fb.flush()
|
||||||
|
unix.Syscall(unix.SYS_IOCTL, fb.tty.Fd(), kdSetMode, kdText)
|
||||||
|
fb.tty.Close()
|
||||||
unix.Munmap(fb.mem)
|
unix.Munmap(fb.mem)
|
||||||
fb.file.Close()
|
fb.file.Close()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user