Starting point for the terminal applications.

This commit is contained in:
2025-07-23 12:51:07 -04:00
parent dd0b0e58d1
commit 619150cfe7
3 changed files with 85 additions and 45 deletions

321
lib/vulgar.sh Executable file
View File

@ -0,0 +1,321 @@
#!/usr/bin/env bash
send_os_command()
{
_splat=""
_suffix=""
echo -n ']'
while [ -n "${1}" ]
do
[ -n '${_splat}' ] && echo -n ';'
echo -n "${1}"
shift 1
done
echo -n "${suffix}"
}
send_csi_command()
{
_splat=""
_suffix="${1}"
shift 1
echo -n ''
echo -n '['
# First one no ';' prefix....
echo -n "${1}"
shift 1
while [ -n "${1}" ]
do
[ -n '${_splat}' ] && echo -n ';'
echo -n "${1}"
shift 1
done
echo -n "${_suffix}"
}
##### START DECCRA Block ############
# These two functions expect DECCRA (DEC Copy Rectangular Area)
# to work. It also requires a second page to copy to.
# I haven't gotten them working, it seems.
save_block()
{
send_csi_command '$v' $* 0 $* 1
}
restore_block()
{
send_csi_command '$v' $* 1 $* 0
}
##### END DECCRA Block ##############
erase_block()
{
send_csi_command '*x' 2
send_csi_command '$r' ${*} 0
send_csi_command '${' ${*}
}
fill_block_attributes()
{
send_csi_command '$r' ${*}
}
fill_block_raw()
{
send_csi_command '$x' ${*}
}
fill_block()
{
_code=`printf '%d' "'$1"`
shift 1
fill_block_raw ${_code} ${*}
}
write_char_raw()
{
fill_block_raw $1 $2 $3 $2 $3
}
write_char()
{
_code=`printf '%d' "'$1"`
shift 1
write_char_raw ${_code} ${*}
}
write_string()
{
_str=$1
shift 1
_row=$1
shift 1
_col=$1
while [ -n "$_str" ]
do
_ch=${_str:0:1}
_str=${_str:1}
_code=`printf '%d' "'$_ch"`
write_char_raw $_code $_row $_col
_col=$(( ${_col} + 1 ))
done
}
draw_box()
{
# T L B R
_T=$1
_L=$2
_B=$3
_R=$4
write_char + $_T $_L
write_char + $_T $_R
write_char + $_B $_L
write_char + $_B $_R
fill_block - $_T $(( $_L + 1 )) $_T $(( $_R - 1 ))
fill_block - $_B $(( $_L + 1 )) $_B $(( $_R - 1 ))
fill_block '|' $(( $_T + 1 )) $_L $(( $_B - 1 )) $_L
fill_block '|' $(( $_T + 1 )) $_R $(( $_B - 1 )) $_R
}
###############
#
# Builds a box of specified dimensions
# (and clears the middle).
#
###############
build_box()
{
erase_block $*
draw_box $*
}
# Read a single keypress in raw terminal mode.
# It will read all codes from the input.
#
# Due to read timeouts, it may give odd
# results on non-interactive terminals.
read_key()
{
seq=""
read -sn 1 key
code=`printf "%x" "'$key"`
seq=${code}
while read -t 0
do
read -sn 1 key
code=`printf "%x" "'$key"`
seq="${seq} ${code}"
done
eval $1=\"${seq}\"
}
translate_key()
{
_codes=${1}
case "${codes}" in
"1b 5b 41")
echo "Up"
;;
"1b 5b 42")
echo "Down"
;;
"1b 5b 44")
echo "Left"
;;
"1b 5b 43")
echo "Right"
;;
"1b")
echo "Escape"
;;
*)
echo "${codes}"
;;
esac
}
#erase_block 20 20 30 30
#fill_block X 21 21 29 29
#write_char Y 25 25
#build_box 8 24 19 99
#write_string "Hello World" 10 26
#read -sn 1 keyA
#read -sn 1 keyB
#read -sn 1 keyC
declare -A buttons
create_button()
{
_name=$1
_r=$2
_c=$3
_text=$4
_color=$5
shift 1
eval button_${_name}=\"$*\"
_T=$_r
_B=$(( $_r + 2 ))
_L=$_c
_R=$(( $_c + 3 + ${#_text} ))
erase_block $_T $_L $_B $_R
build_box $_T $_L $_B $_R
write_string "$_text" $(( $_T + 1 )) $(( $_L + 2 ))
if [ -n "$_color" ]
then
fill_block_attributes $_T $_L $_B $_R "3${_color}"
fi
}
button_stat()
{
_r=$1
_c=$2
_text=$3
_color=$4
}
highlight_button()
{
_name=$1
eval _stat="\${button_${_name}}"
button_stat ${_stat}
_T=$_r
_B=$(( $_r + 2 ))
_L=$_c
_R=$(( $_c + 3 + ${#_text} ))
fill_block_attributes $_T $_L $_B $_R 0
if [ -n "$_color" ]
then
fill_block_attributes $_T $_L $_B $_R "4${_color}"
else
fill_block_attributes $_T $_L $_B $_R '7'
fi
}
unhighlight_button()
{
_name=$1
eval _stat="\${button_${_name}}"
button_stat ${_stat}
_T=$_r
_B=$(( $_r + 2 ))
_L=$_c
_R=$(( $_c + 3 + ${#_text} ))
fill_block_attributes $_T $_L $_B $_R 0
if [ -n "$_color" ]
then
fill_block_attributes $_T $_L $_B $_R "3${_color}"
fi
}
get_terminal_size()
{
send_csi_command t 18
read_key _seq
# Consume ^[[8;
echo "Pre Array: ${_seq}"
_seq=(${_seq})
echo "Array: ${_seq}"
_seq=(${_seq[@]:4})
echo "Trimmed Array: ${_seq}"
_rows=0
while [ "${_seq[ 0 ]}" != ";" ]
do
_rchar="${_seq[ 0 ]}"
echo "RChar: ${_rchar}"
_seq=${_seq[@]:1}
#_rows=$(( ${_rows} * 16 + $( printf "\x${_rchar}" ) ))
done
_cols=0
while [ "${_seq[ 0 ]}" != ";" ]
do
_cchar="${_seq[ 0 ]}"
_seq=${_seq[@]:1}
#_cols=$(( ${_cols} * 16 + $( printf "\x${_cchar}" ) ))
done
eval $1=\"${_rows}\"
eval $2=\"${_cols}\"
}