Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1638714
  • 博文数量: 311
  • 博客积分: 7778
  • 博客等级: 少将
  • 技术积分: 4186
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-09 19:59
个人简介

蓝点工坊(http://www.bluedrum.cn) 创始人,App和嵌入式产品开发。同时也做相应培训和外包工作。 详细介绍 http://pan.baidu.com/s/1y2g88

文章存档

2012年(3)

2011年(115)

2010年(170)

2009年(23)

分类: LINUX

2010-06-27 12:15:01

Andrew Huang
 
因为指导学员做C课程设计,做的终端模下,围棋棋谱显示.其中关于输的几个功能是常用的。就写下来供学员直接调用了。
 
一 设置终端原始模式
 
一是键盘输入要采用特殊输入,在Windows有getch()可用,但Linux需要自已编程.
 
做游戏的特殊要求,输入字符不应该在屏幕显示,输入字符号立刻响应(不需要用回车),能读出特殊键(如方向键)。这一些都能用ncurses库来实现,但是这个库使用起来比较复杂。对于只有C经验的开发者相对要学大量知识,所以不如自己写函数实现。
 上述三个要求换成Linux的表达就是,终端不回显,输入无缓冲,终端不处理特殊键.这种相当于设置终端原始模式。以下是设置原始模式的代码
 

/* 设置终端为原始输入模式

  特征:不回显,不缓冲,不对特殊字符处理
*/

int set_stdin_raw(struct termios * save)
{
  struct termios old;
  
  tcgetattr(0,&old);
//读取当前终端的属性

  *save = old;
  cfmakeraw(&old) ;
//设为原始模式

  
// old.c_lflags &=~(ICANON|ECHO);

  tcsetattr(0,TCSANOW,&old);
//让设置生效

  return 0;
  
}

 
 
二是特殊功能键的识别
 
这个要与原始模式配合,目前识别方向键,Home/End和功能能键,主要是利用实测的结果来实现的
 

#define FUNC_KEY 1000

#define KEY_UP (FUNC_KEY+0)
#define KEY_DOWN (FUNC_KEY+1)
#define KEY_LEFT (FUNC_KEY+2)
#define KEY_RIGHT (FUNC_KEY+3)

#define KEY_FN0 1010
#define KEY_FN(n) (KEY_FN0+n)

#define KEY_HOME KEY_FN(13)
#define KEY_END KEY_FN(14)

//带特殊键的识别

int input_getch()
{
  unsigned char ch ;
  int ret;
        
          read(0,&ch,1);
          
//printf("ch1=%x\n",ch);

         if(ch == 0x1b)
           { /* 特殊键*/
             
//ch = getchar();

             read(0,&ch,1);
            
// printf("ch2=%x\n",ch);

               switch(ch)
                {
             case 0x5b:
                   
//方向键 ,0x41 = UP,0x42=DOWN ,0x43= LEFT,0x44 = RIGHT

                read(0,&ch,1);
                ret = ch-0x41 + KEY_UP;
                break;
             case 0x4f:
                  
//功能键 F1 =0x50,F2=0x51,F3=0x52 ....

                read(0,&ch,1);
               if(ch == 0x48)
                     ret = KEY_HOME;
                 else if(ch == 0x46)
                         ret = KEY_END;
                else
                  ret = KEY_FN(ch-0x4F);
                  
                 
//printf("ch %x,FUNC %d\n",ch,ch-0x4f);

                 break;
                 
                 }
                
        
           }
           else
               ret = ch;
           
               
      return ret;
}

 
三是输入延时检查
 
这个比较常用的功能,这个是在指定时间内没有输入就超时做其它事,如果有键盘输入马上结束延时,比如棋谱重现,按2秒钟一步显示,但是如果用户输入回车键则提前显示下一步。
 
这个要用select 的延时和输入判断功能,代码如下
 


//延时输入函数,如果指定秒数不输入,将自动超时

int input_delay(int sec)
 {
    fd_set fdset;
    struct timeval tv;
    int ret;
    
     tv.tv_sec = sec; //延时2秒

      tv.tv_usec = 0;
    
     FD_ZERO(&fdset);
     
     FD_SET(0,&fdset);
     
     ret = select(1,&fdset,NULL,NULL,&tv);
      //printf("select ret=%d\n",ret);

     if(ret >0)
       {
          return input_getch();
       }
      else
        return 0;
      
 }


完整的测试程序参见附件

 

文件: test_input.zip
大小: 1KB
下载: 下载

阅读(2464) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~