Subject: Re: A problem with read-char
From: rpw3@rpw3.org (Rob Warnock)
Date: Sat, 07 Jun 2008 07:21:36 -0500
Newsgroups: comp.lang.lisp
Message-ID: <WdCdnaGs2JnN4NfVnZ2dnUVZ_vOdnZ2d@speakeasy.net>
Pascal Bourguignon  <pjb@informatimago.com> wrote:
+---------------
| meta.person@gmail.com writes:
| > Is it possible to make read-char behave like getch in С when working
| > with interactive stream (*standard-input*)?
...
| No.  It is not possible.   
| 
| That is, it's not possible with COMMON-LISP:READ-CHAR and neither with
| COMMON-LISP:READ-CHAR-NO-HANG.
...
| The difference is that curses puts the terminal in raw mode to be able
| to receive the characters from the keyboard one at a time, instead of
| leaving the terminal in cooked mode, where the unix driver bufferize
| lines and handles backspace, amongst other niceties.
| 
| Now, I don't know about SBCL, (check the manual of SBCL).  I only have
| the Implementation Notes of CLISP loaded in my wetware.  In CLISP you
| can use the EXT:WITH-KEYBOARD macro (while the basic output features
| of curses are provided by the SCREEN package).
+---------------

If it helps, "meta.person", I once wrote the following for CMUCL
for an application that wanted to be able to type a single character
response to a prompt without messing up the terminal screen:

    (use-package :alien)
    (use-package :unix)
    ...
    (defun read-char-no-echo-cbreak (&optional (stream *query-io*))
      (with-alien ((old (struct termios))
		   (new (struct termios)))
	(let ((e0 (unix-tcgetattr 0 old))
	      (e1 (unix-tcgetattr 0 new))
	      (bits (logior tty-icanon tty-echo tty-echoe
			    tty-echok tty-echonl)))
	  (declare (ignorable e0 e1)) ;[probably should test for error here]
	  (unwind-protect
	      (progn
		(setf (slot new 'c-lflag) (logandc2 (slot old 'c-lflag) bits))
		(setf (deref (slot new 'c-cc) vmin) 1)
		(setf (deref (slot new 'c-cc) vtime) 0)
		(unix-tcsetattr 0 tcsadrain new)
		(read-char stream))
	    (unix-tcsetattr 0 tcsadrain old)))))

SBCL has probably diverged considerably from CMUCL in this area,
but something similar should be doable with SBCL. Start by looking
in the SB-UNIX or maybe the SB-POSIX packages...


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607