term.ui: feature-detect the SU spec (#6844)

pull/6848/head
spaceface777 2020-11-16 13:48:08 +01:00 committed by GitHub
parent b3e19c7247
commit ac8a2ff12d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 4 deletions

View File

@ -168,6 +168,7 @@ mut:
read_buf []byte
print_buf []byte
paused bool
enable_su bool
pub mut:
frame_count u64
window_width int

View File

@ -75,13 +75,31 @@ fn (mut ctx Context) termios_setup() {
print('\x1b]0;$ctx.cfg.window_title\x07')
}
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios)
// feature-test the SU spec
sx, sy := get_cursor_position()
print('$bsu$esu')
ex, ey := get_cursor_position()
if sx == ex && sy == ey {
// the terminal either ignored or handled the sequence properly, enable SU
ctx.enable_su = true
} else {
ctx.draw_line(sx, sy, ex, ey)
ctx.set_cursor_position(sx, sy)
ctx.flush()
}
// Prevent stdin from blocking by making its read time 0
termios.c_cc[C.VTIME] = 0
termios.c_cc[C.VMIN] = 0
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios)
// enable mouse input
print('\x1b[?1003h\x1b[?1006h')
if ctx.cfg.use_alternate_buffer {
// switch to the alternate buffer
print('\x1b[?1049h')
// clear the terminal and set the cursor to the origin
print('\x1b[2J\x1b[3J\x1b[1;1H')
}
ctx.termios = termios
ctx.window_height, ctx.window_width = get_terminal_size()
@ -126,9 +144,41 @@ fn (mut ctx Context) termios_setup() {
c.event(event)
}
})
os.flush()
}
fn get_cursor_position() (int, int) {
print('\033[6n')
// ESC [ YYY `;` XXX `R`
mut reading_x, mut reading_y := false, false
mut x, mut y := 0, 0
for i := 0; i < 15 ; i++ {
ch := int(C.getchar())
b := byte(ch)
i++
// state management:
if b == `R` {
break
} else if b == `[` {
reading_y = true
reading_x = false
continue
} else if b == `;` {
reading_y = false
reading_x = true
continue
}
// converting string vals to ints:
if reading_x {
x = x * 10 + b - byte(`0`)
} else if reading_y {
y = y * 10 + b - byte(`0`)
}
}
return x, y
}
fn termios_reset() {
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH /* C.TCSANOW ?? */, &termios_at_startup)
print('\x1b[?1003l\x1b[?1006l\x1b[?25h')

View File

@ -1,6 +1,5 @@
module ui
import os
import strings
pub struct Color {
@ -19,7 +18,6 @@ pub fn (c Color) hex() string {
const (
bsu = '\x1bP=1s\x1b\\'
esu = '\x1bP=2s\x1b\\'
vno_bsu_esu = os.getenv('VNO_BSU_ESU').len>0
)
[inline]
@ -34,13 +32,13 @@ pub fn (mut ctx Context) flush() {
// TODO
} $else {
// TODO: Diff the previous frame against this one, and only render things that changed?
if vno_bsu_esu {
if !ctx.enable_su {
C.write(C.STDOUT_FILENO, ctx.print_buf.data, ctx.print_buf.len)
} else {
C.write(C.STDOUT_FILENO, bsu.str, bsu.len)
C.write(C.STDOUT_FILENO, ctx.print_buf.data, ctx.print_buf.len)
C.write(C.STDOUT_FILENO, esu.str, esu.len)
}
}
ctx.print_buf.clear()
}
}