免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2440 | 回复: 7
打印 上一主题 下一主题

[C] 关于接受按键输入事件的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-09-13 20:16 |只看该作者 |倒序浏览
本帖最后由 lc-soft 于 2012-09-13 20:21 编辑

先看代码:

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <sys/ioctl.h>
  7. #include <linux/input.h>
  8. #include <fcntl.h>
  9. #include <termios.h>

  10. static struct termios tm;
  11. static int fd = STDIN_FILENO;
  12. int Set_Raw(int t)
  13. {
  14.         if (t > 0) {
  15.                 if(tcgetattr(fd, &tm) < 0) {
  16.                         return -1;  
  17.                 }
  18.                 /* 设置终端为无回显无缓冲模式 */
  19.                 tm.c_lflag &= ~(ICANON|ECHO);
  20.                 tm.c_cc[VMIN] = 1;
  21.                 tm.c_cc[VTIME] = 0;
  22.                 if(tcsetattr(fd, TCSANOW, &tm) < 0) {
  23.                         return -1;
  24.                 }
  25.                 printf("\033[?25l");/* 隐藏光标 */
  26.         } else {
  27.                 tm.c_lflag |= ICANON;
  28.                 tm.c_lflag |= ECHO;
  29.                 tm.c_cc[VMIN] = 1;
  30.                 tm.c_cc[VTIME] = 0;
  31.                 if(tcsetattr(fd,TCSANOW,&tm)<0) {
  32.                         return -1;
  33.                 }
  34.                 printf("\033[?25h"); /* 显示光标 */
  35.         }
  36.         return 0;
  37. }

  38. int main(int argc, char *argv[])
  39. {
  40.         int fd;
  41.         struct input_event event;
  42.         
  43.         Set_Raw(1);
  44.         if( (fd = open("/dev/input/event3", O_RDONLY)) == -1) {
  45.                 printf("error: open keyboard: %s\n",strerror(errno));
  46.                 exit(-1);
  47.         }
  48.         
  49.         while(1){
  50.                 if(read(fd, &event, sizeof(event)) < 0){
  51.                         printf("error\n");
  52.                         return -1;
  53.                 } else {
  54.                         if(event.type == EV_KEY) {
  55.                                 printf("%d, ", event.code);
  56.                                 switch(event.value)
  57.                                 {
  58.                                     case 0: printf("free!\n");break; /* 释放 */
  59.                                     case 1: printf("press!\n");break; /* 按下 */
  60.                                     case 2: printf("pressing!\n");break; /* 按住 */
  61.                                 }
  62.                         }
  63.                 }
  64.         }
  65.         return 0;
  66. }
复制代码
在其它平台上测试,不是/dev/input/event3而是/dev/input/event0;
而且,按住某个键时,显示的结果不是pressing!,而是free!和press!成对显示。
前者倒没什么大碍,可后者,无法获取按键的“按住”状态,对于按键控制的程序,比如:靠长按按键实现某些动作的小游戏,有点不适。


不知有没有更好的解决方法。

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
2 [报告]
发表于 2012-09-13 20:20 |只看该作者
听说终端控制本来就无解的。没什么办法啊。

建议楼主写大字报,统一终端。

不然,只能:1.对各种终端实现不同支持(支持的,则提供该类终端对应的功能及实现)。
2.或是自已读状态,用软件模拟。。。

论坛徽章:
0
3 [报告]
发表于 2012-09-13 20:27 |只看该作者
回复 2# folklore
那,SDL,GTK,QT的按键响应是如何实现的?

SDL的源码我看了一些,是为了想知道它是怎么实现的,可是,没收获什么。。。

SDL_events.c 和 SDL_keyboard.c 中是发现了有关的,SDL_events.c 中有这么个代码:

  1. /* These are global for SDL_eventloop.c */
  2. int SDL_PrivateKeyboard(Uint8 state, SDL_keysym *keysym)
  3. {
  4.     ......
  5. }
复制代码
但是不知道谁会调用 SDL_PrivateKeyboard 函数,而上面那个 注释中说的 SDL_eventloop.c 文件,我没找到。

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
4 [报告]
发表于 2012-09-13 20:33 |只看该作者
回复 3# lc-soft


    我只是听说,不是专家啊。。。。
只是的确也有过和你一样,遇上终端不同响应的。。。
具体情形已忘记了,只记得后面用了不知什么方法应付过去了(反正没解决)。


你说的那些都大公司专人做这事,还怕做不好么。只是相关代码也没去看过。

论坛徽章:
0
5 [报告]
发表于 2012-09-13 20:50 |只看该作者
回复 4# folklore
虽然这些软件是开源的,但读懂也是比较困难,如果有个相关的文档说明项目各个细节就好了,比如原理,流程什么的。

论坛徽章:
0
6 [报告]
发表于 2012-09-14 17:10 |只看该作者
本帖最后由 FaintKnowledge 于 2012-09-14 17:11 编辑

回复 1# lc-soft


    请教下:   |= 是什么意思啊?

论坛徽章:
0
7 [报告]
发表于 2012-09-14 19:36 |只看该作者
本帖最后由 lc-soft 于 2012-09-14 19:37 编辑

回复 6# FaintKnowledge
这是 位运算 , | 就是按位“或”运算, a |= b; 相当于 a = a | b;

论坛徽章:
0
8 [报告]
发表于 2012-09-14 20:24 |只看该作者
回复 7# lc-soft


    呼呼,多谢多谢...没反应过来...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP