summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2015-10-28 18:42:10 (EDT)
committer P. J. McDermott <pj@pehjota.net>2015-10-28 18:57:22 (EDT)
commit9ffcc872fc8866efe70fdb0a5c182c4dd3a2dac9 (patch)
tree5dcd04bc6d8ac655ac704a296778e792c48a77d1
parentc68875b62f2664892822ec5f4459289295c50861 (diff)
downloadfirman.sh-9ffcc872fc8866efe70fdb0a5c182c4dd3a2dac9.zip
firman.sh-9ffcc872fc8866efe70fdb0a5c182c4dd3a2dac9.tar.gz
firman.sh-9ffcc872fc8866efe70fdb0a5c182c4dd3a2dac9.tar.bz2
src/term.sh: New file
-rw-r--r--src/local.mk1
-rw-r--r--src/term.sh266
2 files changed, 267 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+
+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
+}