public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* function to detect keyboard hit
@ 2006-03-13 23:11 Shen, Xinzhuo (US SSA)
  2006-03-13 23:22 ` Sven Eschenberg
  2006-03-14 13:34 ` John Love-Jensen
  0 siblings, 2 replies; 4+ messages in thread
From: Shen, Xinzhuo (US SSA) @ 2006-03-13 23:11 UTC (permalink / raw)
  To: gcc-help

Dear Sir/Madam:

Is there a function in gcc to detect a keyboard hit?  Windows provides a
function _kbhit().  It operates in non-blocking mode, returns 0 until
the user hits a key on the keyboard.  Does gcc have the similar function
to call?

Thanks,

Sean


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

* Re: function to detect keyboard hit
  2006-03-13 23:11 function to detect keyboard hit Shen, Xinzhuo (US SSA)
@ 2006-03-13 23:22 ` Sven Eschenberg
  2006-03-14 13:34 ` John Love-Jensen
  1 sibling, 0 replies; 4+ messages in thread
From: Sven Eschenberg @ 2006-03-13 23:22 UTC (permalink / raw)
  To: Shen, Xinzhuo (US SSA); +Cc: gcc-help

Hi there,

This is not a question of the compiler in use, but rather a question 
about which functionality a lib offers. In this case it's not a part of 
the standard C lib, afaik, and rather os dependant. If the standard c 
lib should offer such functions, you can find it in the library 
documentation ...

-Sven



Shen, Xinzhuo (US SSA) wrote:

>Dear Sir/Madam:
>
>Is there a function in gcc to detect a keyboard hit?  Windows provides a
>function _kbhit().  It operates in non-blocking mode, returns 0 until
>the user hits a key on the keyboard.  Does gcc have the similar function
>to call?
>
>Thanks,
>
>Sean
>
>
>  
>

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

* Re: function to detect keyboard hit
  2006-03-13 23:11 function to detect keyboard hit Shen, Xinzhuo (US SSA)
  2006-03-13 23:22 ` Sven Eschenberg
@ 2006-03-14 13:34 ` John Love-Jensen
  1 sibling, 0 replies; 4+ messages in thread
From: John Love-Jensen @ 2006-03-14 13:34 UTC (permalink / raw)
  To: Shen, Xinzhuo (US SSA), MSX to GCC

Hi Sean,

> Is there a function in gcc to detect a keyboard hit?  Windows provides a
> function _kbhit().  It operates in non-blocking mode, returns 0 until
> the user hits a key on the keyboard.  Does gcc have the similar function
> to call?

That's not a GCC question, it's an OS question.  This is not the right forum
for your question.

Anyway...

Does the OS you are using provide a kbhit routine?

Unix-like OS APIs do not provide that kind of routine.  You can spoof one
up, though (see below).

X11 OS APIs provide something along those lines.

OS X Carbon APIs provide events, which can be used along those lines.

Amiga OS has a magic memory location that can be checked to see if the
keyboard has been hit.

So the question varies, depending on your OS, and what environment (command
line?  Carbon?  X11?  Amiga?  Apple II?  Win32?  Commodore 64?) and which OS
you are using.

For example, <http://www.flipcode.org/cgi-bin/fcarticles.cgi?show=64166>,
which would be for a Unix (POSIX) command line application.  NOTE:  I'd used
ncurses 5.5 for something like this, instead of rolling my own.
ncurses: <http://dickey.his.com/ncurses/announce.html>

Let's say you wanted to use Morgan's routine, but it's C++, and you want C.
I've made it a tiny bit more robust than Morgan's routine by taking out some
hard-coded magic values and put in the kbinit and kbfini routines, and did
it as C instead of C++.  (I've written something similar about 6 years ago,
but it was easier to Google for it than dig out my old SunOS code.)

----------------- kbhit.h -----------------
#ifdef __cplusplus
extern "C" {
#endif
int kbhit();
void kbinit();
void kbfini();
#ifdef __cplusplus
}
#endif

----------------- kbhit.c -----------------
/**
 * Unix C implementation of kbhit(), based on
 * Morgan McGuire, morgan@cs.brown.edu
 * <http://www.flipcode.org/cgi-bin/fcarticles.cgi?show=64166>
 *
 * gcc -c kbhit.c -o kbhit.o
 */

/* --- self-identity --- */
#include "kbhit.h"

/* fileno setbuf stdin */
#include <stdio.h>

/* NULL */
#include <stddef.h>

/* termios tcsetattr tcgetattr TCSANOW */
#include <termios.h>

/* ioctl FIONREAD ICANON ECHO */
#include <sys/ioctl.h>

static int initialized = 0;
static struct termios original_tty;


int kbhit() 
{
  if(!initialized)
  {
    kbinit();
  }

  int bytesWaiting;
  ioctl(fileno(stdin), FIONREAD, &bytesWaiting);
  return bytesWaiting;
}

/* Call this just when main() does its initialization. */
/* Note: kbhit will call this if it hasn't been done yet. */
void kbinit()
{
  struct termios tty;
  tcgetattr(fileno(stdin), &original_tty);
  tty = original_tty;

  /* Disable ICANON line buffering, and ECHO. */
  tty.c_lflag &= ~ICANON;
  tty.c_lflag &= ~ECHO;
  tcsetattr(fileno(stdin), TCSANOW, &tty);

  /* Decouple the FILE*'s internal buffer. */
  /* Rely on the OS buffer, probably 8192 bytes. */
  setbuf(stdin, NULL);
  initialized = 1;
}

/* Call this just before main() quits, to restore TTY settings! */
void kbfini()
{
  if(initialized)
  {
    tcsetattr(fileno(stdin), TCSANOW, &original_tty);
    initialized = 0;
  }
}

----------------------------------

To use kbhit:

----------------- demo_kbhit.c -----------------
/* gcc demo_kbhit.c kbhit.c -o demo_kbhit */
#include "kbhit.h"
#include <unistd.h>
#include <stdio.h>

int main()
{
  int c;
  printf("Press 'x' to quit\n");
  fflush(stdin);
  do
  {
    if(kbhit())
    {
      c = fgetc(stdin);
      printf("Bang: %c!\n", c);
      fflush(stdin);
    }
    else usleep(1000); /* Sleep for a millisecond. */
  } while(c != 'x');
}

----------------------------------

Hope that helps,
--Eljay

PS:  Morgan approved of my modifications, and thought I should share.

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

* Re: function to detect keyboard hit
@ 2006-03-16 15:15 kenneth kahn
  0 siblings, 0 replies; 4+ messages in thread
From: kenneth kahn @ 2006-03-16 15:15 UTC (permalink / raw)
  To: gcc-help

Here's a variation of the code already given; I've tried it with success on
AIX, Solaris, HP-UX, Linux and WinXP:

/* get_char.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>

int getch(void);   // wait for next keystroke (no echo)
int getchp(void);  // check for pending keystrokes (no echo)

int main () {
   int key;
   /*----------------------------------------------------------*
    ! Continue waiting for keystrokes until ESC is pressed     !
    *----------------------------------------------------------*/
   while (!(((key = getch()) == 0x1b) && (getchp() < 0))) {
     printf("key=%04x",key);
     /*--------------------------------------------------------*
      ! search for any pending keystrokes (e.g. function keys) !
      *--------------------------------------------------------*/
     while ((key = getchp()) > 0) {
       printf(" %04x",key);
     }
     printf("\n");
   }
   /*----------------------------------------------------------*
    ! ESC pressed; exit program                                !
    *----------------------------------------------------------*/
   printf("Escape Pressed\n");
   return 0;
}

/*----------------------------------------------------------*
  ! Wait for the next keypress (no echo)                     !
  *----------------------------------------------------------*/
int getch(void) {
   struct termios term_settings,term_settings_saved;
   int x;
   if (tcgetattr(STDIN_FILENO,&term_settings))
     return -1;
   term_settings_saved=term_settings;
   term_settings.c_lflag &= ~ICANON ;
   term_settings.c_lflag &= ~ECHO ;
   term_settings.c_cc[VMIN]=1 ;
   term_settings.c_cc[VTIME]=0;
   if (tcsetattr (STDIN_FILENO, TCSANOW, &term_settings) < 0)
   x=getchar();
   tcsetattr (STDIN_FILENO, TCSANOW, &term_settings_saved);
   return x;
}

/*----------------------------------------------------------*
  ! Check for pending keystrokes (no echo)                   !
  *----------------------------------------------------------*/
int getchp(void) {
   struct termios term_settings,term_settings_saved;
   char c;
   int x;
   if (tcgetattr(STDIN_FILENO,&term_settings))
     return -2;
   term_settings_saved=term_settings;
   term_settings.c_lflag &= ~ICANON ;
   term_settings.c_lflag &= ~ECHO ;
   term_settings.c_cc[VMIN]=0;
   term_settings.c_cc[VTIME]=0;
   if (tcsetattr (STDIN_FILENO, TCSANOW, &term_settings) < 0)
     return -2;
   x = getchar();
   tcsetattr (STDIN_FILENO, TCSANOW, &term_settings_saved);
   return x;
}

-----------------------------------
Kenneth Kahn
Senior Member of Consulting Staff
CVA R&D Hardware Emulation
Cadence Design Systems
Lake Katrine, NY

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

end of thread, other threads:[~2006-03-16 15:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-13 23:11 function to detect keyboard hit Shen, Xinzhuo (US SSA)
2006-03-13 23:22 ` Sven Eschenberg
2006-03-14 13:34 ` John Love-Jensen
2006-03-16 15:15 kenneth kahn

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 read-only IMAP folder(s) and NNTP newsgroup(s).