[comp.lang.c] NOVICE question: How to know when a key is pressed

etxpihl@tore.ericsson.se (DEE Tomas Pihl) (04/11/91)

Here comes a tricky question that I (the novice swede) can't solve.

I want to know how you can scan if a specific key has been pressed.
Just as this program I'm using know know that i press eg. ESC.
I don't want the pressed key to be echoed out to the screen as it is
with getchar().

Please, help me. 

-------------------
Tomas Pihl    E-mail: etxpihl@texas.ericsson.se 

scott@bbxsda.UUCP (Scott Amspoker) (04/12/91)

In article <1991Apr11.155200.12819@ericsson.se> etxpihl@tore.ericsson.se (DEE Tomas Pihl) writes:
>I want to know how you can scan if a specific key has been pressed.
>Just as this program I'm using know know that i press eg. ESC.
>I don't want the pressed key to be echoed out to the screen as it is
>with getchar().

What you want is to be able to read individual key strokes without
echo.  There is no standard way to do it.  On unix/xenix systems
check the ioctl() calls in your manual.  On MSDOS you can perform
raw console I/O (again, check the manual).  Another newsgroup can
probably provide a better answer.

-- 
Scott Amspoker                       | Touch the peripheral convex of every
Basis International, Albuquerque, NM | kind, then various kinds of blaming
(505) 345-5232                       | sound can be sent forth.
unmvax.cs.unm.edu!bbx!bbxsda!scott   |    - Instructions for a little box that
                                     |      blurts out obscenities.

rogue@cellar.UUCP (Rogue Winter) (04/13/91)

etxpihl@tore.ericsson.se (DEE Tomas Pihl) writes:

> I want to know how you can scan if a specific key has been pressed.
> Just as this program I'm using know know that i press eg. ESC.
> I don't want the pressed key to be echoed out to the screen as it is
> with getchar().
> 
I'm amazed.  I can actually ANSWER a question here!

There are two functions in Microsoft C (I'm not sure if they're ANSI or MS 
defined) called getch() and getche() that you may find useful.

getchar() does not just echo the character to the screen.  getchar() uses the 
computer's character buffer to store and pass characters.  Useful for 
full-word commands, but a horror when you need single-key response.  The 
getch() and getche() functionsbypass the character buffer and offer an 
immediate response.

The difference is that getch() will not echo characters to the screen (your 
desired effect), while getche() will (you may not want it now, but you may in 
the future).  The syntax, like getchar() is:

        ch = getch()

To use getch() and getche(), you need to #include <conio.h> (console i/o) in 
your preprocessor commands.

rogue winter     : "Never trust a gentleman any further than you can throw
rogue@cellar.uucp: his valet."

raymond@math.berkeley.edu (Raymond Chen) (04/13/91)

In article <1991Apr11.155200.12819@ericsson.se>, etxpihl@tore (DEE Tomas Pihl) writes:
>I want to know how you can scan if a specific key has been pressed. ...

You didn't say what operating system you were using, so I'll assume you're
using what I'm using.

The keyboard strobe lives at $C000; when a key is available, the top bit
goes on.  The lower seven bits contain the ASCII code of the key that was
pressed.  To clear the strobe, access memory location $C010.  Note also
that if the high bit of $C062 is clear, you should convert uppercase ASCII
characters to lowercase; this is the standard method for entering lowercase
for those who have installed the `shift key mod' by connecting the BUTTON2
pin on the game controller chip to the second connector pin on the keyboard
decoder card.  (Only works for newer keyboards; for older ones, you'll need
to do some soldering.)

Hope this helps.
--
This article has not been closed-captioned for the humor-impaired.
[Easy extra credit:  What computer system am I describing?]

richd@hplvec.LVLD.HP.COM (Rich Dykstra) (04/13/91)

On hp systems, two things must be done - change the terminal driver
configuration, and modify the terminal straps so that escape sequences
are  passed to the host instead of being acted upon locally by the
terminal.  Here is code I created several years ago, I think it is
still relevant: (refer to termio(7))




static  struct  termio  tcorg_block;
static  struct  termio  tcact_block;
static  struct  f_rec_t tcara[TCARA];
        struct  key_rec{    int key; char   chr};
tcinit()
{
    int result;

    printf("%c&s1A", 27);                       /* transmit esc sequences*/
    result = ioctl(0, TCGETA, &tcorg_block);    /* driver data (origial) */
    result = ioctl(0, TCGETA, &tcact_block);    /* driver dat (to mess with)*/
    tcact_block.c_lflag &= ~ICANON & ~ECHO;     /* no echo or pre process*/
    tcact_block.c_cc[VEOF] = 1;                 /* read 1 char at a time*/
    result = ioctl(0, TCSETA, &tcact_block);    /* set the driver       */
    tcmove(0,0,'S');                            /* clear the screen */
}



As an alternative, you may want to consider using the curses package. It
does this as well as offering other slick interfacing features, such as
terminal type independence.