term.ui: feature-detect the SU spec (#6844)
parent
b3e19c7247
commit
ac8a2ff12d
|
@ -168,6 +168,7 @@ mut:
|
||||||
read_buf []byte
|
read_buf []byte
|
||||||
print_buf []byte
|
print_buf []byte
|
||||||
paused bool
|
paused bool
|
||||||
|
enable_su bool
|
||||||
pub mut:
|
pub mut:
|
||||||
frame_count u64
|
frame_count u64
|
||||||
window_width int
|
window_width int
|
||||||
|
|
|
@ -75,13 +75,31 @@ fn (mut ctx Context) termios_setup() {
|
||||||
print('\x1b]0;$ctx.cfg.window_title\x07')
|
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
|
// Prevent stdin from blocking by making its read time 0
|
||||||
termios.c_cc[C.VTIME] = 0
|
termios.c_cc[C.VTIME] = 0
|
||||||
termios.c_cc[C.VMIN] = 0
|
termios.c_cc[C.VMIN] = 0
|
||||||
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios)
|
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios)
|
||||||
|
// enable mouse input
|
||||||
print('\x1b[?1003h\x1b[?1006h')
|
print('\x1b[?1003h\x1b[?1006h')
|
||||||
if ctx.cfg.use_alternate_buffer {
|
if ctx.cfg.use_alternate_buffer {
|
||||||
|
// switch to the alternate buffer
|
||||||
print('\x1b[?1049h')
|
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.termios = termios
|
||||||
ctx.window_height, ctx.window_width = get_terminal_size()
|
ctx.window_height, ctx.window_width = get_terminal_size()
|
||||||
|
@ -126,9 +144,41 @@ fn (mut ctx Context) termios_setup() {
|
||||||
c.event(event)
|
c.event(event)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
os.flush()
|
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() {
|
fn termios_reset() {
|
||||||
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH /* C.TCSANOW ?? */, &termios_at_startup)
|
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH /* C.TCSANOW ?? */, &termios_at_startup)
|
||||||
print('\x1b[?1003l\x1b[?1006l\x1b[?25h')
|
print('\x1b[?1003l\x1b[?1006l\x1b[?25h')
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
module ui
|
module ui
|
||||||
|
|
||||||
import os
|
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
pub struct Color {
|
pub struct Color {
|
||||||
|
@ -19,7 +18,6 @@ pub fn (c Color) hex() string {
|
||||||
const (
|
const (
|
||||||
bsu = '\x1bP=1s\x1b\\'
|
bsu = '\x1bP=1s\x1b\\'
|
||||||
esu = '\x1bP=2s\x1b\\'
|
esu = '\x1bP=2s\x1b\\'
|
||||||
vno_bsu_esu = os.getenv('VNO_BSU_ESU').len>0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
|
@ -34,13 +32,13 @@ pub fn (mut ctx Context) flush() {
|
||||||
// TODO
|
// TODO
|
||||||
} $else {
|
} $else {
|
||||||
// TODO: Diff the previous frame against this one, and only render things that changed?
|
// 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)
|
C.write(C.STDOUT_FILENO, ctx.print_buf.data, ctx.print_buf.len)
|
||||||
} else {
|
} else {
|
||||||
C.write(C.STDOUT_FILENO, bsu.str, bsu.len)
|
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, ctx.print_buf.data, ctx.print_buf.len)
|
||||||
C.write(C.STDOUT_FILENO, esu.str, esu.len)
|
C.write(C.STDOUT_FILENO, esu.str, esu.len)
|
||||||
}
|
}
|
||||||
ctx.print_buf.clear()
|
ctx.print_buf.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue