LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 07-15-2007, 05:06 PM   #1
ilnli
Member
 
Registered: Jul 2004
Location: Pakistan
Distribution: Slackware 10.0, SUSE 9.1, RH 7, 7.3, 8, 9, FC2
Posts: 406

Rep: Reputation: 32
key press detecting


I have a loop which updates display but now I want that when user presses a key 'q' then it goes to some other function etc. I can't use getch() cause it will top the loop and waits for user key, is there any other way in linux C that I can detect a key and then check its value?

regards,
Imran
 
Old 07-16-2007, 12:00 AM   #2
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
I'm going to answer slightly more than you ask, but the following will give you all you need to know in this area, without using curses. You'll be particularly interested in hurltty; its first read blocks, but its second read does not.

anykey.c

Code:
/*
 * This program reads a single key, and then exits without echoing it.
 */

#include <stdio.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>

int main(void)
{
  int            count;
  int            jndex;
  int            result;

  char           in_buffer[80];

  struct termios tp1;
  struct termios tp2;

  tcgetattr(0,&tp1);

  tp2=tp1;

  tp2.c_iflag&=~ICRNL;
  tp2.c_lflag&=~ICANON;
  tp2.c_lflag&=~ECHO;
  tp2.c_cc[VMIN ]=1;
  tp2.c_cc[VTIME]=0;
  tp2.c_cc[VINTR]=0xFF;
  tp2.c_cc[VSUSP]=0xFF;
  tp2.c_cc[VQUIT]=0xFF;

  tcsetattr(0,TCSANOW,&tp2);

  do
  {
    in_buffer[0]=0;

    count=read(0,in_buffer,1);

  } while(0);

  tcsetattr(0,TCSANOW,&tp1);

  result=in_buffer[0]&0xFF;

  return result;

} /* main(void) */
dumptty.c:

Code:
/*
 * This program dumps the terminal characteristics of stdin and stdout.
 */

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

#define COLUMNS 3
#define ITEMS_PER_COLUMN ((NCCS+COLUMNS-1)/COLUMNS)

//----------------------------------------------------------------------------

void print_flag(unsigned long  status,
                unsigned long  mask,
                char          *name
               )
{
  if(status&mask)
  {
    printf("         0x%08X %s",status&mask,name);

    if((status&mask)!=mask)
      printf(" (from 0x%08X)",mask);

    printf("\n");
  }

} /* print_flag(unsigned long,unsigned long) */

//----------------------------------------------------------------------------

void print_speed(speed_t  the_speed,
                 char   * the_label
                )
{
  printf("         %s speed flag is %2d: ",
         the_label,
         the_speed
        );

  switch(the_speed)
  {
    case B0    : printf("    0 baud\n"         ); break;
    case B50   : printf("   50 baud\n"         ); break;
    case B75   : printf("   75 baud\n"         ); break;
    case B110  : printf("  110 baud\n"         ); break;
    case B134  : printf("  134.5 baud\n"       ); break;
    case B150  : printf("  150 baud\n"         ); break;
    case B200  : printf("  200 baud\n"         ); break;
    case B300  : printf("  300 baud\n"         ); break;
    case B600  : printf("  600 baud\n"         ); break;
    case B1200 : printf(" 1200 baud\n"         ); break;
    case B1800 : printf(" 1800 baud\n"         ); break;
    case B2400 : printf(" 2400 baud\n"         ); break;
    case B4800 : printf(" 4800 baud\n"         ); break;
    case B9600 : printf(" 9600 baud\n"         ); break;
    case B19200: printf("19200 baud\n"         ); break;
    case B38400: printf("38400 baud\n"         ); break;
    default    : printf("undefined baud rate\n"); break;
  }

} // print_speed(speed_t,char*)

//----------------------------------------------------------------------------

void print_result(char           *channel_name,
                  int             result_in,
                  struct termios *tp
                 )
{
  int     jndex;
  int     kndex;

  printf("result for %s was %d\n\n",channel_name,result_in);

  if(result_in==0)
  {
    printf("c_iflag: 0x%08X\n",tp->c_iflag);

    print_flag(tp->c_iflag,IGNBRK ,"IGNBRK");
    print_flag(tp->c_iflag,BRKINT ,"BRKINT");
    print_flag(tp->c_iflag,IGNPAR ,"IGNPAR");
    print_flag(tp->c_iflag,PARMRK ,"PARMRK");
    print_flag(tp->c_iflag,INPCK  ,"INPCK ");
    print_flag(tp->c_iflag,ISTRIP ,"ISTRIP");
    print_flag(tp->c_iflag,INLCR  ,"INLCR ");
    print_flag(tp->c_iflag,IGNCR  ,"IGNCR ");
    print_flag(tp->c_iflag,ICRNL  ,"ICRNL ");
    print_flag(tp->c_iflag,IUCLC  ,"IUCLC ");
    print_flag(tp->c_iflag,IXON   ,"IXON  ");
    print_flag(tp->c_iflag,IXANY  ,"IXANY ");
    print_flag(tp->c_iflag,IXOFF  ,"IXOFF ");
    print_flag(tp->c_iflag,IMAXBEL,"IMAXBEL");

    printf("\nc_oflag: 0x%08X\n",tp->c_oflag);

    print_flag(tp->c_oflag,OPOST  ,"OPOST  ");
    print_flag(tp->c_oflag,OLCUC  ,"OLCUC  ");
    print_flag(tp->c_oflag,ONLCR  ,"ONLCR  ");
    print_flag(tp->c_oflag,OCRNL  ,"OCRNL  ");
    print_flag(tp->c_oflag,ONOCR  ,"ONOCR  ");
    print_flag(tp->c_oflag,ONLRET ,"ONLRET ");
    print_flag(tp->c_oflag,OFILL  ,"OFILL  ");
    print_flag(tp->c_oflag,OFDEL  ,"OFDEL  ");
    print_flag(tp->c_oflag,NLDLY  ,"NLDLY  ");
    print_flag(tp->c_oflag,CRDLY  ,"CRDLY  ");
    print_flag(tp->c_oflag,TABDLY ,"TABDLY ");
    print_flag(tp->c_oflag,BSDLY  ,"BSDLY  ");
    print_flag(tp->c_oflag,VTDLY  ,"VTDLY  ");
    print_flag(tp->c_oflag,FFDLY  ,"FFDLY  ");

    printf("\nc_cflag: 0x%08X\n",tp->c_cflag);

    print_flag(tp->c_cflag,CBAUD  ,"CBAUD  ");

    print_speed(cfgetispeed(tp),"input ");
    print_speed(cfgetospeed(tp),"output");

    print_flag(tp->c_cflag,CSIZE  ,"CSIZE  ");
    print_flag(tp->c_cflag,CSTOPB ,"CSTOPB ");
    print_flag(tp->c_cflag,CREAD  ,"CREAD  ");
    print_flag(tp->c_cflag,PARENB ,"PARENB ");
    print_flag(tp->c_cflag,PARODD ,"PARODD ");
    print_flag(tp->c_cflag,HUPCL  ,"HUPCL  ");
    print_flag(tp->c_cflag,CLOCAL ,"CLOCAL ");
    print_flag(tp->c_cflag,CIBAUD ,"CIBAUD ");
    print_flag(tp->c_cflag,CRTSCTS,"CRTSCTS");

    printf("\nc_lflag: 0x%08X\n",tp->c_lflag);

    print_flag(tp->c_lflag,ISIG   ,"ISIG   ");
    print_flag(tp->c_lflag,ICANON ,"ICANON ");
    print_flag(tp->c_lflag,XCASE  ,"XCASE  ");
    print_flag(tp->c_lflag,ECHO   ,"ECHO   ");
    print_flag(tp->c_lflag,ECHOE  ,"ECHOE  ");
    print_flag(tp->c_lflag,ECHOK  ,"ECHOK  ");
    print_flag(tp->c_lflag,ECHONL ,"ECHONL ");
    print_flag(tp->c_lflag,NOFLSH ,"NOFLSH ");
    print_flag(tp->c_lflag,TOSTOP ,"TOSTOP ");
    print_flag(tp->c_lflag,ECHOCTL,"ECHOCTL");
    print_flag(tp->c_lflag,ECHOPRT,"ECHOPRT");
    print_flag(tp->c_lflag,ECHOKE ,"ECHOKE ");
    print_flag(tp->c_lflag,FLUSHO ,"FLUSHO ");
    print_flag(tp->c_lflag,PENDIN ,"PENDIN ");
    print_flag(tp->c_lflag,IEXTEN ,"IEXTEN ");

    printf("\n");

    for(jndex=0;jndex<NCCS;jndex++)
    {
      kndex=(jndex/COLUMNS)+ITEMS_PER_COLUMN*(jndex%COLUMNS);

      printf("%2d ",kndex);

      switch(kndex)
      {
        case  0: printf("VINTR   "); break;
        case  1: printf("VQUIT   "); break;
        case  2: printf("VERASE  "); break;
        case  3: printf("VKILL   "); break;
        case  4: printf("VEOF    "); break;
        case  5: printf("VTIME   "); break;
        case  6: printf("VMIN    "); break;
        case  7: printf("VSWTCH  "); break;
        case  8: printf("VSTART  "); break;
        case  9: printf("VSTOP   "); break;
        case 10: printf("VSUSP   "); break;
        case 11: printf("VEOL    "); break;
        case 12: printf("VREPRINT"); break;
        case 13: printf("VDISCARD"); break;
        case 14: printf("VWERASE "); break;
        case 15: printf("VLNEXT  "); break;
        case 16: printf("VEOL2   "); break;
        default: printf("--------"); break;
      }

      printf(" %02X  ",tp->c_cc[kndex]);

      if(jndex%COLUMNS==COLUMNS-1)
        printf("\n");
    }

    if(jndex%COLUMNS!=COLUMNS-1)
      printf("\n");

    printf("\n");
  }

} /* print_result(char *,int,struct termios) */

//----------------------------------------------------------------------------

int main(void)
{
  int            jndex;
  int            result0;
  int            result1;

  struct termios tp0;
  struct termios tp1;

  for(jndex=0;jndex<1;jndex++)
  {
    result0=tcgetattr(0,&tp0);
    result1=tcgetattr(1,&tp1);

    print_result("stdin", result0,&tp0);
    print_result("stdout",result1,&tp1);

    /* sleep(1); */
  }

} /* main(void) */
hurltty.c:

Code:
/*
 * This program waits for a character.  It then outputs that character
 * repeatedly until another character is input, and then outputs that
 * character repeatedly until and so on.
 */

#include <stdio.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>

int main(void)
{
  int            count;
  int            jndex;
  int            result;
  int            virgin;

  char           echoed_data;

  char           in_buffer[80];

  struct termios tp1;
  struct termios tp2;

  virgin=1;
  echoed_data='X';

  printf("Type a space character to exit.\n");

  tcgetattr(0,&tp1);

  tp2=tp1;

  tp2.c_iflag&=~ICRNL;
  tp2.c_lflag&=~ICANON;
  tp2.c_lflag&=~ECHO;
  tp2.c_cc[VMIN ]=1;
  tp2.c_cc[VTIME]=0;
  tp2.c_cc[VINTR]=0xFF;
  tp2.c_cc[VSUSP]=0xFF;
  tp2.c_cc[VQUIT]=0xFF;

  tcsetattr(0,TCSANOW,&tp2);

  do
  {
    in_buffer[0]=0;

    count=read(0,in_buffer,1);

    if(virgin)
    {
      virgin=0;

      tp2.c_cc[VMIN]=0;

      tcsetattr(0,TCSANOW,&tp2);
    }

    if(count>0)
      echoed_data=in_buffer[0];

    printf("%c",echoed_data);

    fflush(stdout);

  } while(echoed_data!=0x20);

  printf("\n");

  tcsetattr(0,TCSANOW,&tp1);

} /* main(void) */
nudgetty.c:

Code:
/*
 * This program repeatedly reads a single keystroke without echoing it, and
 * dumps its value in hex and decimal.  But it does not block when reading; if
 * it doesn't get a character within a certain period of time, it outputs
 * hyphens and then goes back to reading.
 */

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>

volatile int ding_flag;

void alarm_dinger(int something)
{
  ding_flag=1;

} // alarm_dinger(void)

int main(void)
{
  int              count;
  int              done;
  int              jndex;
  int              result;

  char             in_buffer[80];

  struct sigaction new_action;
  struct sigaction old_action;

  struct termios   tp1;
  struct termios   tp2;

  done=0;

  printf("Type a space character to exit.\n");

  tcgetattr(0,&tp1);

  tp2=tp1;

  tp2.c_iflag&=~ICRNL;
  tp2.c_lflag&=~ICANON;
  tp2.c_lflag&=~ECHO;
  tp2.c_cc[VMIN ]=1;
  tp2.c_cc[VTIME]=0;
  tp2.c_cc[VINTR]=0xFF;
  tp2.c_cc[VSUSP]=0xFF;
  tp2.c_cc[VQUIT]=0xFF;

  tcsetattr(0,TCSANOW,&tp2);

  new_action.sa_handler=alarm_dinger;
  new_action.sa_flags=0;

  ding_flag=0;

  if(sigaction(SIGALRM,&new_action,&old_action))
  {
    printf("couldn't arm signal\n");

    done=1;
  }

  alarm(5);

  while(!done)
  {
    in_buffer[0]=0;

    count=read(0,in_buffer,1);

    if(ding_flag)
    {
      ding_flag=0;

      printf("--- --  ");

      fflush(stdout);

      alarm(5);
    }
    else
    {
      printf("%3d %02X  ",
             (unsigned char)in_buffer[0],
             (unsigned char)in_buffer[0]
            );

      fflush(stdout);

      if(in_buffer[0]==0x20)
      {
        done=1;
      }
    }
  }

  if(sigaction(SIGALRM,&old_action,NULL))
  {
    printf("couldn't disarm signal\n");

    done=1;
  }

  printf("\n");

  tcsetattr(0,TCSANOW,&tp1);

} /* main(void) */
playtty.c:

Code:
/*
 * This program repeatedly reads a character from the keyboard, blocking but
 * not echoing.  It displays in decimal and hex the value of the character and
 * then goes back for more.
 */

#include <stdio.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>

int main(void)
{
  int            count;
  int            jndex;
  int            result;

  char           in_buffer[80];

  struct termios tp1;
  struct termios tp2;

  printf("Type a space character to exit.\n");

  tcgetattr(0,&tp1);

  tp2=tp1;

  tp2.c_iflag&=~ICRNL;
  tp2.c_lflag&=~ICANON;
  tp2.c_lflag&=~ECHO;
  tp2.c_cc[VMIN ]=1;
  tp2.c_cc[VTIME]=0;
  tp2.c_cc[VINTR]=0xFF;
  tp2.c_cc[VSUSP]=0xFF;
  tp2.c_cc[VQUIT]=0xFF;

  tcsetattr(0,TCSANOW,&tp2);

  do
  {
    in_buffer[0]=0;

    count=read(0,in_buffer,1);

    printf("%3d %02X  ",
           (unsigned char)in_buffer[0],
           (unsigned char)in_buffer[0]
          );

    fflush(stdout);

  } while(in_buffer[0]!=0x20);

  printf("\n");

  tcsetattr(0,TCSANOW,&tp1);

} /* main(void) */
Hope this helps.
 
Old 07-16-2007, 02:24 AM   #3
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,786

Rep: Reputation: 282Reputation: 282Reputation: 282
You can use select() to check if input is available on stdin. And you can set the terminal to RAW mode (something that's probably done in the examples above using tcsetattr() )
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
c++ g++ wait for key press??? blizunt7 Programming 15 07-13-2007 02:09 AM
Key press Majestros Programming 2 02-14-2007 03:42 AM
Key press simulation in FC kiruxa Linux - General 1 11-24-2006 10:00 PM
Double key press on Keyboard Zettai Linux - Newbie 2 03-09-2005 10:59 PM
Gnome - strange key press problem Horos23 Linux - Software 3 03-04-2005 04:05 AM


All times are GMT -5. The time now is 05:29 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration