linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* getch()
       [not found] <200211071046.24987.abulfazl@juniv.edu>
@ 2002-11-07 15:35 ` Progga
  2002-11-07 18:04   ` getch() Elias Athanasopoulos
  0 siblings, 1 reply; 9+ messages in thread
From: Progga @ 2002-11-07 15:35 UTC (permalink / raw)
  To: linux-c-programming


Hello,

  Is there any way to get a character without pressing return in a simple
 console application ( something like getch() of ncurses ) ? It's needed in
 a test shell for getting the arrow keypresses for using the history list.
 TIA.

  Khoda Hafez
  Progga


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: getch()
  2002-11-07 18:04   ` getch() Elias Athanasopoulos
@ 2002-11-07 17:19     ` Glynn Clements
  2002-11-07 20:58       ` getch() Elias Athanasopoulos
  2002-11-08  9:04     ` getch() Progga
  1 sibling, 1 reply; 9+ messages in thread
From: Glynn Clements @ 2002-11-07 17:19 UTC (permalink / raw)
  To: Elias Athanasopoulos; +Cc: Progga, linux-c-programming


Elias Athanasopoulos wrote:

> >   Is there any way to get a character without pressing return in a simple
> >  console application ( something like getch() of ncurses ) ? It's needed in
> >  a test shell for getting the arrow keypresses for using the history list.
> >  TIA.
> 
> Yes. Test it before, it is old code...
> 
> Using the code below, I had a loop (it is from a console game I
> was trying to write 4-5 years before):

This is basically the right approach (i.e. use tcsetattr() to disable
canonical mode).

However, I'll just mention a couple of other points:

>     while (ch! = 'q') {

>       fflush (stdin);

fflush() is only applicable to output streams; using it on input
streams seems to be a common programming "superstition".

> And, what was _UP and _LEFT? Hmm... 
> 
> [anteater@neutrino berserkers]$ grep _UP *.h
> #define _UP 65
> [anteater@neutrino berserkers]$ grep _LEFT *.h
> #define TOP_LEFT 51
> #define BOT_LEFT 52
> #define _LEFT 68

IOW, 'A', 'B', 'C', 'D'. I doubt that you were actually using those
keys; more likely, assuming that the cursor keys generated particular
sequences and ignoring most of the sequence.

If you want to use extended keys (those which generate sequences
rather than individual codes, e.g. cursor keys, function keys, numeric
keypad, etc), use termcap/terminfo. Or just use curses; when someone
wants getch(), they often want the other stuff which curses provides.

> struct termios saved_attrib;
> 
> void reset_input_mode(void)
> {
> 	tcsetattr(STDIN_FILENO, TCSANOW, &saved_attrib);
> }

[snip]

> 	atexit(reset_input_mode);

To be safe, you should also install signal handlers which restore the
terminal mode.

-- 
Glynn Clements <glynn.clements@virgin.net>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: getch()
  2002-11-07 15:35 ` getch() Progga
@ 2002-11-07 18:04   ` Elias Athanasopoulos
  2002-11-07 17:19     ` getch() Glynn Clements
  2002-11-08  9:04     ` getch() Progga
  0 siblings, 2 replies; 9+ messages in thread
From: Elias Athanasopoulos @ 2002-11-07 18:04 UTC (permalink / raw)
  To: Progga; +Cc: linux-c-programming

On Thu, Nov 07, 2002 at 09:35:59PM +0600, Progga wrote:
>   Is there any way to get a character without pressing return in a simple
>  console application ( something like getch() of ncurses ) ? It's needed in
>  a test shell for getting the arrow keypresses for using the history list.
>  TIA.

Yes. Test it before, it is old code...

Using the code below, I had a loop (it is from a console game I
was trying to write 4-5 years before):

    while (ch! = 'q') {
      fflush (stdin);
      if (read (STDIN_FILENO, &ch, 1) > 0) 
	if (ch >= _UP && ch <= _LEFT) 
	  {
	    check_move (ch);
	    ...
	  }
	....
	....
    }		

And, what was _UP and _LEFT? Hmm... 

[anteater@neutrino berserkers]$ grep _UP *.h
#define _UP 65
[anteater@neutrino berserkers]$ grep _LEFT *.h
#define TOP_LEFT 51
#define BOT_LEFT 52
#define _LEFT 68

Elias

--CUT HERE--

/*
 * Changing Terminal attributes using low level terminal handling,
 * in order to have non-buffered, non-echoed, non-blocking input.
 * 
 * */

#include <stddef.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

struct termios saved_attrib;

void reset_input_mode(void)
{
	tcsetattr(STDIN_FILENO, TCSANOW, &saved_attrib);
}

void set_input_mode(void)
{
	struct termios attrib;
	char *name;
	
	/* check stdin is a terminal */
	
	if (!isatty(STDIN_FILENO)) {
		fprintf(stderr, "Not a terminal!\n");
		exit(EXIT_FAILURE);
	}
	
	/* save original attributes */
	
	tcgetattr(STDIN_FILENO, &saved_attrib);
	atexit(reset_input_mode);
	
	/* make the changes */
	
	tcgetattr(STDIN_FILENO, &attrib);
	attrib.c_lflag &= ~(ICANON|ECHO); /* disables canonical mode, echo */
	attrib.c_cc[VMIN] = 0;            /* non-blocking input */
	attrib.c_cc[VTIME] = 0;
	tcsetattr(STDIN_FILENO, TCSAFLUSH, &attrib);
}


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: getch()
  2002-11-07 17:19     ` getch() Glynn Clements
@ 2002-11-07 20:58       ` Elias Athanasopoulos
  0 siblings, 0 replies; 9+ messages in thread
From: Elias Athanasopoulos @ 2002-11-07 20:58 UTC (permalink / raw)
  To: Glynn Clements; +Cc: Progga, linux-c-programming

On Thu, Nov 07, 2002 at 05:19:51PM +0000, Glynn Clements wrote:
> fflush() is only applicable to output streams; using it on input
> streams seems to be a common programming "superstition".

Correct. I really can't tell why this was there. :-) (I can't also
tell why I didn't see the bogocity while copy-pasting it...)

> > [anteater@neutrino berserkers]$ grep _LEFT *.h
> > #define TOP_LEFT 51
> > #define BOT_LEFT 52
> > #define _LEFT 68
> 
> IOW, 'A', 'B', 'C', 'D'. I doubt that you were actually using those
> keys; more likely, assuming that the cursor keys generated particular
> sequences and ignoring most of the sequence.

Yes. IIRC, each arrow kay had a sequence of 3 codes. I was matching only
the first one, because otherwise (i.e. by matching each one of the 3 codes) 
the game was too slow. :-)

Elias

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: getch()
  2002-11-07 18:04   ` getch() Elias Athanasopoulos
  2002-11-07 17:19     ` getch() Glynn Clements
@ 2002-11-08  9:04     ` Progga
  2002-11-08 17:51       ` getch() Glynn Clements
  2002-12-05 12:17       ` defining a #define Christopher Quinn
  1 sibling, 2 replies; 9+ messages in thread
From: Progga @ 2002-11-08  9:04 UTC (permalink / raw)
  To: linux-c-programming


> 	tcgetattr(STDIN_FILENO, &attrib);
> 	attrib.c_lflag &= ~(ICANON|ECHO); /* disables canonical mode, echo */
> 	attrib.c_cc[VMIN] = 0;            /* non-blocking input */
> 	attrib.c_cc[VTIME] = 0;
> 	tcsetattr(STDIN_FILENO, TCSAFLUSH, &attrib);

 Thanks all for the super suggestions. I only had to change one line for 
getting what I need :

 > 	attrib.c_cc[VMIN] = 0;            /* non-blocking input */
to
 	attrib.c_cc[VMIN] = 1;            /* blocking input */

 If input is taken in non-blocking mode then something like:

  while( read( STDIN_FILENO, &ch, 1 ) != 1 ) ;

  needs to be used. It's also OK. But to use getchar()/cin, using blocking 
mode appeared the most suitable. So I did the change. The chance to control 
the echo and nonecho mode is another beauty. I needed the nonecho and it was 
already in the code. Thanks again from me and my friend Mahbub.

 Khoda Hafez 
 Progga


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: getch()
  2002-11-08  9:04     ` getch() Progga
@ 2002-11-08 17:51       ` Glynn Clements
  2002-12-05 12:17       ` defining a #define Christopher Quinn
  1 sibling, 0 replies; 9+ messages in thread
From: Glynn Clements @ 2002-11-08 17:51 UTC (permalink / raw)
  To: abulfazl; +Cc: linux-c-programming


Progga wrote:

>  If input is taken in non-blocking mode then something like:
> 
>   while( read( STDIN_FILENO, &ch, 1 ) != 1 ) ;
> 
>   needs to be used.

NO! This will result in a "busy wait", consuming all available CPU
time.

If you want to wait until a byte is actually available to be read,
either:

a) don't use non-blocking mode in the first place,
b) temporarily disable non-blocking mode, or
c) use select() to wait until input is available.

-- 
Glynn Clements <glynn.clements@virgin.net>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* defining a #define
  2002-11-08  9:04     ` getch() Progga
  2002-11-08 17:51       ` getch() Glynn Clements
@ 2002-12-05 12:17       ` Christopher Quinn
  2002-12-05 13:22         ` Miguel Griffa
  1 sibling, 1 reply; 9+ messages in thread
From: Christopher Quinn @ 2002-12-05 12:17 UTC (permalink / raw)
  To: linux-c-programming

if i compile a library with a certain build flag
there are times when i would like to reflect that flag
into the header file for the library, so that larger
compilations involving the library are built the same
way.

ie. something like

---library.h---
#ifdef BUILD_THIS_WAY
#text "#define BUILD_THIS_WAY"
#endif

i could not find anything in the gnu cpp docs.
but does anyone know for sure there *is* a way?

thanks.
- chris



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: defining a #define
  2002-12-05 12:17       ` defining a #define Christopher Quinn
@ 2002-12-05 13:22         ` Miguel Griffa
  2002-12-05 13:36           ` Christopher Quinn
  0 siblings, 1 reply; 9+ messages in thread
From: Miguel Griffa @ 2002-12-05 13:22 UTC (permalink / raw)
  To: Christopher Quinn; +Cc: linux-c-programming

Just what you did is ok

#ifdef LINUX
#define GREAT_API
#define OS "Linux"
#else
#define UNKNOWN
#endif


Christopher Quinn wrote:
Christopher Quinn wrote:

> if i compile a library with a certain build flag
> there are times when i would like to reflect that flag
> into the header file for the library, so that larger
> compilations involving the library are built the same
> way.
>
> ie. something like
>
> ---library.h---
> #ifdef BUILD_THIS_WAY
> #text "#define BUILD_THIS_WAY"
> #endif
>
> i could not find anything in the gnu cpp docs.
> but does anyone know for sure there *is* a way?
>
> thanks.
> - chris
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe 
> linux-c-programming" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


> if i compile a library with a certain build flag
> there are times when i would like to reflect that flag
> into the header file for the library, so that larger
> compilations involving the library are built the same
> way.
>
> ie. something like
>
> ---library.h---
> #ifdef BUILD_THIS_WAY
> #text "#define BUILD_THIS_WAY"
> #endif
>
> i could not find anything in the gnu cpp docs.
> but does anyone know for sure there *is* a way?
>
> thanks.
> - chris
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe 
> linux-c-programming" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: defining a #define
  2002-12-05 13:22         ` Miguel Griffa
@ 2002-12-05 13:36           ` Christopher Quinn
  0 siblings, 0 replies; 9+ messages in thread
From: Christopher Quinn @ 2002-12-05 13:36 UTC (permalink / raw)
  To: Miguel Griffa; +Cc: linux-c-programming

sorry - i wish i could withdraw that question, as it
was ridiculous!
thanks.
- chris

Miguel Griffa wrote:

> Just what you did is ok
>
> #ifdef LINUX
> #define GREAT_API
> #define OS "Linux"
> #else
> #define UNKNOWN
> #endif
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2002-12-05 13:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <200211071046.24987.abulfazl@juniv.edu>
2002-11-07 15:35 ` getch() Progga
2002-11-07 18:04   ` getch() Elias Athanasopoulos
2002-11-07 17:19     ` getch() Glynn Clements
2002-11-07 20:58       ` getch() Elias Athanasopoulos
2002-11-08  9:04     ` getch() Progga
2002-11-08 17:51       ` getch() Glynn Clements
2002-12-05 12:17       ` defining a #define Christopher Quinn
2002-12-05 13:22         ` Miguel Griffa
2002-12-05 13:36           ` Christopher Quinn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).