# ANSI/DEC-compatible terminal manipulation # # Copyright (C) 2015 Patrick "P. J." McDermott # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . term_tty= term_byte= term_num_lines= term_num_columns= term_init() { term_tty="$(tty)" read -r term_num_lines term_num_columns <<-EOF $(stty size) EOF return 0 } term_lines() { printf '%d' ${term_num_lines} return 0 } term_columns() { printf '%d' ${term_num_columns} return 0 } term_echo() { stty echo return 0 } term_noecho() { stty -echo return 0 } term_raw() { stty raw return 0 } term_cooked() { stty cooked return 0 } term_cursor_up() { local n="${1}" shift 1 # CUU printf '\033[%dA' ${n} >"${term_tty}" return 0 } term_cursor_down() { local n="${1}" shift 1 # CUD printf '\033[%dB' ${n} >"${term_tty}" return 0 } term_cursor_forward() { local n="${1}" shift 1 # CUF printf '\033[%dC' ${n} >"${term_tty}" return 0 } term_cursor_back() { local n="${1}" shift 1 # CUB printf '\033[%dD' ${n} >"${term_tty}" return 0 } term_cursor_position() { local row="${1}" local col="${2}" shift 2 # CUP printf '\033[%d;%dH' ${row} ${col} >"${term_tty}" return 0 } term_clear() { # ED with n=2 printf '\033[2J' >"${term_tty}" term_cursor_position 1 1 return 0 } term_hide_cursor() { # DECTCEM with code "l" printf '\033[?25l' >"${term_tty}" return 0 } term_show_cursor() { # DECTCEM with code "h" printf '\033[?25h' >"${term_tty}" return 0 } term_attr_on() { local attr="${1}" shift 1 local attr_code= case "${attr}" in blink) attr_code=5;; bold) attr_code=1;; dim) attr_code=2;; invis) attr_code=8;; reverse) attr_code=7;; underline) attr_code=4;; *) return 1;; esac # SGR printf '\033[%dm' ${attr_code} >"${term_tty}" return 0 } term_attr_off() { local attr="${1}" shift 1 local attr_code= case "${attr}" in blink) attr_code=25;; bold) attr_code=22;; dim) attr_code=22;; invis) attr_code=28;; reverse) attr_code=27;; underline) attr_code=24;; *) return 1;; esac # SGR printf '\033[%dm' ${attr_code} >"${term_tty}" return 0 } term_fg_color_set() { local color="${1}" shift 1 case "${color}" in black) color=0;; red) color=1;; green) color=2;; yellow) color=3;; blue) color=4;; magenta) color=5;; cyan) color=6;; white) color=7;; *) return 1;; esac # SGR printf '\033[%dm' $((30 + $color)) >"${term_tty}" return 0 } term_bg_color_set() { local color="${1}" shift 1 case "${color}" in black) color=0;; red) color=1;; green) color=2;; yellow) color=3;; blue) color=4;; magenta) color=5;; cyan) color=6;; white) color=7;; *) return 1;; esac # SGR printf '\033[%dm' $((40 + $color)) >"${term_tty}" return 0 } term_attr_reset() { # SGR printf '\033[0m' >"${term_tty}" return 0 } _term_get_byte() { # Damn command substitutions eat trailing whitespace. Even if # whitespace is the /only/ thing printed and exactly what we want from # the command. term_byte="$(dd bs=1 count=1 2>/dev/null; printf '.')" term_byte="${term_byte%.}" return 0 } term_getch() { local byte= byte="$(getbyte)" case "${byte}" in "$(printf '\033')") case "$(getbyte)" in '[') case "$(getbyte)" in 'A') key=KEY_UP;; 'B') key=KEY_DOWN;; 'C') key=KEY_RIGHT;; 'D') key=KEY_LEFT;; *) key=KEY_INV;; esac ;; *) key=KEY_INV;; esac ;; ' ') key=KEY_SPACE;; "${HT}") key=KEY_TAB;; "${LF}") key=KEY_ENTER;; *) key="${byte}";; esac printf '%s' "${key}" return 0 }