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,7 +32,7 @@ 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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue