From: Rob Warnock on 14 Nov 2009 08:28 Bigos <ruby.object(a)googlemail.com> wrote: +--------------- | Jurgen Defurne <jurgen.defu...(a)telenet.be> wrote: | > schreef Bigos: | > > I think I have found something about cl-ncurses which might be useful. | > > Maybe I was giving up too soon. ooops | > | > I used a combination of stty and the standard input functions of | > Common Lisp. I really did not want to screw around with calling C | > functions inside Common Lisp. | > | > stty-raw; <common Lisp program here>;stty-cooked | | I know Jurgen's idea should work, but can anybody provide simple | example? Help will be appreciated. +--------------- Here's a little function I hacked up in CMUCL some years ago when I needed single character terminal input for an interactive program [running on FreeBSD & Linux]: (use-package :alien) (use-package :unix) #| What "less" does: s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); s.c_oflag |= (OPOST|ONLCR|TAB3); s.c_oflag &= ~(OCRNL|ONOCR|ONLRET); s.c_cc[VMIN] = 1; s.c_cc[VTIME] = 0; |# (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)) (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))))) And here's a typical use of it: (defun space-or-q-p (&optional (prompt "[More... (q to quit)] ")) (format *query-io* "~A" prompt) (force-output *query-io*) (let* ((c (read-char-no-echo-cbreak *query-io*)) (bs (make-string (1+ (length prompt)) :initial-element #\backspace)) (sp (make-string (1+ (length prompt)) :initial-element #\space))) (format *query-io* "~A~A~A" bs sp bs) (force-output *query-io*) (char-equal c #\q))) As I said, this is CMUCL-specific, but almost any CL implementation should provide you *some* way to make "ioctl()" calls... -Rob ----- Rob Warnock <rpw3(a)rpw3.org> 627 26th Avenue <URL:http://rpw3.org/> San Mateo, CA 94403 (650)572-2607
From: Thomas F. Burdick on 14 Nov 2009 13:35 On Nov 13, 12:48 am, Bigos <ruby.obj...(a)googlemail.com> wrote: > Also I am willing to consider some alternatives, for example some > simple GUI tool-kit. Since you mention this, if you use Ltk you can easily bind keypress events. It wouldn't be based around a read-keypress function, but instead, whenever your program is in the idle loop and the user presses a key, your callback function gets called. It's the easiest way in Lisp to get text in a window and/or circles, lines, rectangles, etc.
From: Bigos on 14 Nov 2009 14:38 On Nov 14, 1:28 pm, r...(a)rpw3.org (Rob Warnock) wrote: > Bigos <ruby.obj...(a)googlemail.com> wrote: > > +--------------- > | Jurgen Defurne <jurgen.defu...(a)telenet.be> wrote: > | > schreef Bigos: > | > > I think I have found something about cl-ncurses which might be useful. > | > > Maybe I was giving up too soon. ooops > | > > | > I used a combination of stty and the standard input functions of > | > Common Lisp. I really did not want to screw around with calling C > | > functions inside Common Lisp. > | > > | > stty-raw; <common Lisp program here>;stty-cooked > | > | I know Jurgen's idea should work, but can anybody provide simple > | example? Help will be appreciated. > +--------------- > > Here's a little function I hacked up in CMUCL some years ago when I > needed single character terminal input for an interactive program > [running on FreeBSD & Linux]: > > (use-package :alien) > (use-package :unix) > > #| What "less" does: > s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); > s.c_oflag |= (OPOST|ONLCR|TAB3); > s.c_oflag &= ~(OCRNL|ONOCR|ONLRET); > s.c_cc[VMIN] = 1; > s.c_cc[VTIME] = 0; > |# > > (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)) > (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))))) > > And here's a typical use of it: > > (defun space-or-q-p (&optional (prompt "[More... (q to quit)] ")) > (format *query-io* "~A" prompt) > (force-output *query-io*) > (let* ((c (read-char-no-echo-cbreak *query-io*)) > (bs (make-string (1+ (length prompt)) :initial-element #\backspace)) > (sp (make-string (1+ (length prompt)) :initial-element #\space))) > (format *query-io* "~A~A~A" bs sp bs) > (force-output *query-io*) > (char-equal c #\q))) > > As I said, this is CMUCL-specific, but almost any CL implementation > should provide you *some* way to make "ioctl()" calls... > > -Rob > > ----- > Rob Warnock <r...(a)rpw3.org> > 627 26th Avenue <URL:http://rpw3.org/> > San Mateo, CA 94403 (650)572-2607 I use sbcl and it doesn't seem to work for me. I get lots of error messages, which I don't understand. I think it's something to do with the packages. Also I am surprised that you need so much code for such seemingly trivial function. I the other language I use it's only 3 lines of code. system("stty raw -echo") #execute command in subshell raw mode, no echo char=STDIN.getc #read character from standard input system("stty -raw echo") #reset terminal mode Is something similar possible with sbcl?
From: Bigos on 14 Nov 2009 14:45 On Nov 14, 7:38 pm, Bigos <ruby.obj...(a)googlemail.com> wrote: > On Nov 14, 1:28 pm, r...(a)rpw3.org (Rob Warnock) wrote: > > > > > > > Bigos <ruby.obj...(a)googlemail.com> wrote: > > > +--------------- > > | Jurgen Defurne <jurgen.defu...(a)telenet.be> wrote: > > | > schreef Bigos: > > | > > I think I have found something about cl-ncurses which might be useful. > > | > > Maybe I was giving up too soon. ooops > > | > > > | > I used a combination of stty and the standard input functions of > > | > Common Lisp. I really did not want to screw around with calling C > > | > functions inside Common Lisp. > > | > > > | > stty-raw; <common Lisp program here>;stty-cooked > > | > > | I know Jurgen's idea should work, but can anybody provide simple > > | example? Help will be appreciated. > > +--------------- > > > Here's a little function I hacked up in CMUCL some years ago when I > > needed single character terminal input for an interactive program > > [running on FreeBSD & Linux]: > > > (use-package :alien) > > (use-package :unix) > > > #| What "less" does: > > s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); > > s.c_oflag |= (OPOST|ONLCR|TAB3); > > s.c_oflag &= ~(OCRNL|ONOCR|ONLRET); > > s.c_cc[VMIN] = 1; > > s.c_cc[VTIME] = 0; > > |# > > > (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)) > > (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))))) > > > And here's a typical use of it: > > > (defun space-or-q-p (&optional (prompt "[More... (q to quit)] ")) > > (format *query-io* "~A" prompt) > > (force-output *query-io*) > > (let* ((c (read-char-no-echo-cbreak *query-io*)) > > (bs (make-string (1+ (length prompt)) :initial-element #\backspace)) > > (sp (make-string (1+ (length prompt)) :initial-element #\space))) > > (format *query-io* "~A~A~A" bs sp bs) > > (force-output *query-io*) > > (char-equal c #\q))) > > > As I said, this is CMUCL-specific, but almost any CL implementation > > should provide you *some* way to make "ioctl()" calls... > > > -Rob > > > ----- > > Rob Warnock <r...(a)rpw3.org> > > 627 26th Avenue <URL:http://rpw3.org/> > > San Mateo, CA 94403 (650)572-2607 > > I use sbcl and it doesn't seem to work for me. I get lots of error > messages, which I don't understand. I think it's something to do with > the packages. > > Also I am surprised that you need so much code for such seemingly > trivial function. I the other language I use it's only 3 lines of > code. > > system("stty raw -echo") #execute command in subshell raw mode, no > echo > char=STDIN.getc #read character from standard input > system("stty -raw echo") #reset terminal mode > > Is something similar possible with sbcl? is sb-ext:run-program similar to Ruby's system()
From: Rob Warnock on 14 Nov 2009 20:56
Bigos <ruby.object(a)googlemail.com> wrote: +--------------- | r...(a)rpw3.org (Rob Warnock) wrote: ....[how to do raw/cbreak input from within CMCUL]... | > As I said, this is CMUCL-specific, but almost any CL implementation | > should provide you *some* way to make "ioctl()" calls... | | I use sbcl and it doesn't seem to work for me. +--------------- (*Ahem!*) As I *SAID*, my code is CMUCL-specific, but almost any CL implementation should provide you *some* way to make "ioctl()" calls. SBCL certainly provides such a way, but it's not at all surprising that it's *different* from CMUCL -- see the SBCL documentation for how to do the corresponding thing. +--------------- | Also I am surprised that you need so much code for such seemingly | trivial function. I the other language I use it's only 3 lines of | code. | | system("stty raw -echo") #execute command in subshell raw mode, no | echo | char=STDIN.getc #read character from standard input | system("stty -raw echo") #reset terminal mode +--------------- You're "fork()/exec()"-ing *two* external programs!! My example code does everything those two external program executions do *inside* the original process. Anyway, who cares how much code it is? You're going to use an application-specific wrapper function around it anyway, aren't you? +--------------- | Is something similar possible with sbcl? +--------------- Yes. RTFM. -Rob ----- Rob Warnock <rpw3(a)rpw3.org> 627 26th Avenue <URL:http://rpw3.org/> San Mateo, CA 94403 (650)572-2607 |