What to use for conio?

cpghost cpghost at cordula.ws
Sat Sep 15 01:58:49 PDT 2007


On Sat, 15 Sep 2007 03:11:54 -0500 (CDT)
Lars Eighner <luvbeastie at larseighner.com> wrote:

> What I really want to do:  capture keypresses (including function
> keys) from a (virtual) terminal without their echoing or without
> having to enter a new line (i.e. hit return).
> 
> Why I do not want to use (n)curses: to use keypad in ncurses, I have
> to initscr() and ncurses will then blank the screen and seize the
> terminal. I do not want that to happen.  I want to write ANSI
> directly to the terminal and get non-echoing keypresses back.

Check out tcgetattr(3) and tcsetattr(3) from <termios.h>,

Here's an entry from the Python FAQ that you can adapt or
retrofit to C:

How do I get a single keypress at a time?
-----------------------------------------

For Unix variants: There are several solutions. It's straightforward
to do this using curses, but curses is a fairly large module to learn.
Here's a solution without curses:

import termios, fcntl, sys, os, select
   
fd = sys.stdin.fileno()
   
oldterm = termios.tcgetattr(fd)
newattr = oldterm[:]
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
   
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
   
try:
    while 1:
        r, w, e = select.select([fd], [], [])
        if r:
            c = sys.stdin.read(1)
            print "Got character", repr(c)
            if c == "q":
                break # quit
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
   
   You need the termios and the fcntl module for any of this to work,
and I've only tried it on Linux, though it should work elsewhere. In
this code, characters are read and printed one at a time, until the
user presses `q' to quit. 

   termios.tcsetattr() turns off stdin's echoing and disables canonical
mode. fcntl.fnctl() is used to obtain stdin's file descriptor flags and
modify them for non-blocking mode. The select module is then used to
wait for incoming characters.

------------ END OF FAQ ENTRY ------------------------------------

> Why I think I need something like conio:  I think I could get stdio
> to do what I want if I had something like kbdhit from conio, but
> conio doesn't exist pretty much anywhere outside of DOS.  I'm pretty
> sure the system conSio is not anything like what I want.
> 
> So how can I get non-echoing keypress without turning my terminal
> over to the tender mercies of ncurses?

s. above.

-- 
Cordula's Web. http://www.cordula.ws/


More information about the freebsd-questions mailing list