From 9ffcc872fc8866efe70fdb0a5c182c4dd3a2dac9 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Wed, 28 Oct 2015 18:42:10 -0400 Subject: src/term.sh: New file --- diff --git a/src/local.mk b/src/local.mk index 15b33ec..2f5b4b5 100644 --- a/src/local.mk +++ b/src/local.mk @@ -7,6 +7,7 @@ firman_SOURCES += \ src/log.sh \ src/main.sh \ src/rand.sh \ + src/term.sh \ src/ui.sh include $(top_srcdir)/src/action/local.mk diff --git a/src/term.sh b/src/term.sh new file mode 100644 index 0000000..f6b8a00 --- /dev/null +++ b/src/term.sh @@ -0,0 +1,266 @@ +# 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_init() +{ + term_tty="$(tty)" + + 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_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 +} -- cgit v0.9.1