Skip to content

Commit

Permalink
Add terminal mode switch utility experimentally
Browse files Browse the repository at this point in the history
  • Loading branch information
shirok committed Sep 17, 2014
1 parent c9d06fb commit 3300d32
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
@@ -1,3 +1,7 @@
2014-09-16 Shiro Kawai <shiro@acm.org>

* ext/termios/termios.scm (with-terminal-mode): Experimentally added.

2014-09-15 Shiro Kawai <shiro@acm.org>

* lib/gauche/interactive.scm (describe): Improve output of
Expand Down
52 changes: 50 additions & 2 deletions ext/termios/termios.scm
Expand Up @@ -89,6 +89,54 @@
(without-echoing #f read-line))
|#



;; mode should be either one of 'cooked, 'rare or 'raw
;; NB: Although we work on the given port and also calls PROC with port,
;; what's changed is actually a device connected to the port. There can
;; be more than one port connected to the same device, and I/O thru those
;; ports would also be affected.
;; TODO: What to do with Windows console?
(define (with-terminal-mode port mode proc)
(cond
[(sys-isatty port)
(let ()
(define saved-attr (sys-tcgetattr port))
(define new-attr
(rlet1 attr (sys-termios-copy saved-attr)
(case mode
[(raw)
(set! (~ attr'iflag)
(logand (~ attr'iflag)
(lognot (logior BRKINT ICRNL INPCK ISTRIP IXON))))
(set! (~ attr'oflag) (logand (~ attr'oflag) (lognot OPOST)))
(set! (~ attr'cflag) (logand (~ attr'cflag) (lognot CS8)))
(set! (~ attr'lflag)
(logand (~ attr'lflag)
(lognot (logior ECHO ICANON IEXTEN ISIG))))]
[(rare)
(set! (~ attr'iflag)
(logior BRKINT
(logand (~ attr'iflag)
(lognot (logior ICRNL INPCK ISTRIP IXON)))))
(set! (~ attr'oflag) (logand (~ attr'oflag) (lognot OPOST)))
(set! (~ attr'cflag) (logand (~ attr'cflag) (lognot CS8)))
(set! (~ attr'lflag)
(logior ISIG
(logand (~ attr'lflag)
(lognot (logior ECHO ICANON IEXTEN)))))]
[(cooked)
(set! (~ attr'iflag)
(logior (~ attr'iflag)
BRKINT ICRNL INPCK ISTRIP IXON))
(set! (~ attr'oflag) (logior (~ attr'oflag) OPOST))
(set! (~ attr'lflag)
(logior (~ attr'lflag) ECHO ICANON IEXTEN ISIG))]
[else
(error "terminal mode needs to be one of cooked, rare or raw, \
but got:" mode)])))
(define (set)
(sys-tcsetattr port TCSANOW new-attr))
(define (reset)
(sys-tcsetattr port TCSANOW saved-attr))
(unwind-protect (begin (set) (proc port)) (reset)))]
[else (proc port)]))

0 comments on commit 3300d32

Please sign in to comment.