mirror of
https://github.com/vlang/v.git
synced 2025-09-09 15:27:05 -04:00
parent
4a1c7add24
commit
5b44b67211
29
examples/term_key_pressed.v
Normal file
29
examples/term_key_pressed.v
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
import term
|
||||||
|
import time
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
unbuffer_stdout()
|
||||||
|
println('Press Ctrl-D or ESC to exit.')
|
||||||
|
|
||||||
|
term.enable_echo(false)
|
||||||
|
mut frame := 0
|
||||||
|
for {
|
||||||
|
print('\r${time.now()} | frame: ${frame:06} | ')
|
||||||
|
x := term.key_pressed()
|
||||||
|
if x in [i64(0), 4, 27] {
|
||||||
|
// pressing Ctrl-D or ESC exits the loop
|
||||||
|
// Ctrl-D mean EOF sometimes, so return 0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if x > 0 {
|
||||||
|
println('${x:08x}')
|
||||||
|
}
|
||||||
|
time.sleep(16 * time.millisecond)
|
||||||
|
frame++
|
||||||
|
}
|
||||||
|
term.enable_echo(true)
|
||||||
|
|
||||||
|
println('done')
|
||||||
|
}
|
@ -2,6 +2,7 @@ module term
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import term.termios
|
import term.termios
|
||||||
|
import time
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
@ -215,3 +216,68 @@ pub fn graphics_num_colors() u16 {
|
|||||||
}
|
}
|
||||||
return buf.bytestr().u16()
|
return buf.bytestr().u16()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// enable_echo enable/disable echo input characters
|
||||||
|
pub fn enable_echo(enable bool) {
|
||||||
|
mut state := termios.Termios{}
|
||||||
|
termios.tcgetattr(0, mut state)
|
||||||
|
if enable {
|
||||||
|
state.c_lflag |= C.ECHO
|
||||||
|
} else {
|
||||||
|
state.c_lflag &= ~C.ECHO
|
||||||
|
}
|
||||||
|
termios.tcsetattr(0, C.TCSANOW, mut state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyPressedParams contains the optional parameters that you can pass to key_pressed.
|
||||||
|
@[params]
|
||||||
|
pub struct KeyPressedParams {
|
||||||
|
pub mut:
|
||||||
|
blocking bool // whether to wait for a pressed key
|
||||||
|
echo bool // whether to output the pressed key to stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
// key_pressed gives back a single character, read from the standard input.
|
||||||
|
// It returns -1 on error or no character in non-blocking mode
|
||||||
|
pub fn key_pressed(params KeyPressedParams) i64 {
|
||||||
|
mut state := termios.Termios{}
|
||||||
|
if termios.tcgetattr(0, mut state) != 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
mut old_state := state
|
||||||
|
defer {
|
||||||
|
// restore the old terminal state:
|
||||||
|
termios.tcsetattr(0, C.TCSANOW, mut old_state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable line by line input
|
||||||
|
state.c_lflag &= ~C.ICANON
|
||||||
|
|
||||||
|
if params.echo {
|
||||||
|
state.c_lflag |= C.ECHO
|
||||||
|
} else {
|
||||||
|
state.c_lflag &= ~C.ECHO
|
||||||
|
}
|
||||||
|
termios.tcsetattr(0, C.TCSANOW, mut state)
|
||||||
|
|
||||||
|
mut ret := i64(0)
|
||||||
|
|
||||||
|
for {
|
||||||
|
pending := os.fd_is_pending(0)
|
||||||
|
if pending {
|
||||||
|
r := C.read(0, &ret, 8)
|
||||||
|
if r < 0 {
|
||||||
|
return r
|
||||||
|
} else {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !params.blocking {
|
||||||
|
// in non-blocking mode, we need to return immediately
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
time.sleep(1 * time.millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
module term
|
module term
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
#include <conio.h>
|
||||||
|
|
||||||
@[typedef]
|
@[typedef]
|
||||||
pub struct C.COORD {
|
pub struct C.COORD {
|
||||||
@ -156,3 +159,54 @@ pub fn graphics_num_colors() u16 {
|
|||||||
// does not have support for querying the graphics setup this call returns 0
|
// does not have support for querying the graphics setup this call returns 0
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// enable_echo enable/disable echo input characters
|
||||||
|
pub fn enable_echo(enable bool) {
|
||||||
|
// no need under windows, use key_pressed func's echo
|
||||||
|
}
|
||||||
|
|
||||||
|
fn C.kbhit() bool
|
||||||
|
fn C._getch() int
|
||||||
|
fn C._getche() int
|
||||||
|
|
||||||
|
// KeyPressedParams contains the optional parameters that you can pass to key_pressed.
|
||||||
|
@[params]
|
||||||
|
pub struct KeyPressedParams {
|
||||||
|
pub mut:
|
||||||
|
blocking bool // whether to wait for a pressed key
|
||||||
|
echo bool // whether to output the pressed key to stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
// key_pressed gives back a single character, read from the standard input.
|
||||||
|
// It returns -1 on error or no character in non-blocking mode
|
||||||
|
pub fn key_pressed(params KeyPressedParams) i64 {
|
||||||
|
for {
|
||||||
|
if C.kbhit() {
|
||||||
|
res := if params.echo {
|
||||||
|
C._getche()
|
||||||
|
} else {
|
||||||
|
C._getch()
|
||||||
|
}
|
||||||
|
// see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getche-getwche?view=msvc-170
|
||||||
|
// > When _getche or _getwche reads a function key or an arrow key, the function must be called twice;
|
||||||
|
// > the first call returns 0 or 0xE0, and the second call returns the actual key code.
|
||||||
|
if res in [0, 0xe0] {
|
||||||
|
if C.kbhit() {
|
||||||
|
res2 := if params.echo {
|
||||||
|
C._getche()
|
||||||
|
} else {
|
||||||
|
C._getch()
|
||||||
|
}
|
||||||
|
return i64(u32(0xe0) << 16 | u32(res2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i64(res)
|
||||||
|
}
|
||||||
|
if !params.blocking {
|
||||||
|
// in non-blocking mode, we need to return immediately
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
time.sleep(1 * time.millisecond)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user