萌夫养成记txt下载:linux下如何模拟按键输入和模拟鼠标 - qiuye - JavaEye技术网站

来源:百度文库 编辑:九乡新闻网 时间:2024/05/08 12:35:45
MMC卡和SD卡的区别 |Linux root file system

linux下如何模拟按键输入和模拟鼠标

查看/dev/input/eventX是什么类型的事件, cat /proc/bus/input/devices

设备有着自己特殊的按键键码,我需要将一些标准的按键,比如0-9,X-Z等模拟成标准按键,比如KEY_0,KEY-Z等,所以需要用到按键模拟,具体方法就是操作/dev/input/event1文件,向它写入个input_event结构体就可以模拟按键的输入了。

linux/input.h中有定义,这个文件还定义了标准按键的编码等

C代码
  1. struct input_event {  
  2.          struct timeval time; //按键时间  
  3.          __u16 type; //类型,在下面有定义  
  4.          __u16 code; //要模拟成什么按键  
  5.          __s32 value;//是按下还是释放  
  6. };  
 



code:

事件的代码.如果事件的类型代码是EV_KEY,该代码code为设备键盘代码.代码植0~127为键盘上的按键代码,0x110~0x116 为鼠标上按键代码,其中0x110(BTN_LEFT)为鼠标左键,0x111(BTN_RIGHT)为鼠标右键,0x112(BTN_MIDDLE)为鼠标中键.其它代码含义请参看include/linux/input.h文件.如果事件的类型代码是EV_REL,code值表示轨迹的类型.如指示鼠标的X轴方向REL_X(代码为0x00),指示鼠标的Y轴方向REL_Y(代码为0x01),指示鼠标中轮子方向REL_WHEEL(代码为0x08).

type:

EV_KEY,键盘

EV_REL,相对坐标

EV_ABS,绝对坐标

value:

事件的值.如果事件的类型代码是EV_KEY,当按键按下时值为1,松开时值为0;如果事件的类型代码是EV_ REL,value的正数值和负数值分别代表两个不同方向的值.

C代码
  1. /* 
  2. * Event types 
  3. */  
  4.   
  5. #define EV_SYN 0x00  
  6. #define EV_KEY 0x01 //按键  
  7. #define EV_REL 0x02 //相对坐标(轨迹球)  
  8. #define EV_ABS 0x03 //绝对坐标  
  9. #define EV_MSC 0x04 //其他  
  10. #define EV_SW 0x05  
  11. #define EV_LED 0x11 //LED  
  12. #define EV_SND 0x12//声音  
  13. #define EV_REP 0x14//repeat  
  14. #define EV_FF 0x15  
  15. #define EV_PWR 0x16  
  16. #define EV_FF_STATUS 0x17  
  17. #define EV_MAX 0x1f  
  18. #define EV_CNT (EV_MAX+1)  
 



1。模拟按键输入

C代码
  1. //其中0表示释放,1按键按下,2表示一直按下  
  2.   
  3. //0 for EV_KEY for release, 1 for keypress and 2 for autorepeat.  
  4.   
  5. void simulate_key(int fd,int value)  
  6.   
  7. {  
  8.          struct input_event event;  
  9.          event.type = EV_KEY;  
  10.          //event.code = KEY_0;//要模拟成什么按键  
  11.          event.value = value;//是按下还是释放按键或者重复  
  12.          gettimeofday(&event.time,0);  
  13.          if(write(fd,&event,sizeof(event)) < 0){  
  14.                   dprintk("simulate key error~~~\n");  
  15.          return ;  
  16.          }  
  17. }  
 



2。模拟鼠标输入(轨迹球)

C代码
  1. void simulate_mouse(int fd,char buf[4])  
  2. {  
  3.          int rel_x,rel_y;  
  4.          static struct input_event event,ev;  
  5.   
  6.          //buf[0],buf[2],小于0则为左移,大于0则为右移  
  7.          //buf[1],buf[3],小于0则为下移,大于0则为上移  
  8.          dprintk("MOUSE TOUCH: x1=%d,y1=%d,x2=%d,y2=%d\n",buf[0],buf[1],buf[2],buf[3]);  
  9.   
  10.          rel_x = (buf[0] + buf[2]) /2;  
  11.          rel_y = -(buf[1] + buf[3]) /2; //和我们的鼠标是相反的方向,所以取反  
  12.          event.type = EV_REL;  
  13.          event.code = REL_X;  
  14.          event.value = rel_x;  
  15.          gettimeofday(&event.time,0);  
  16.   
  17.          if( write(fd,&event,sizeof(event))!=sizeof(event))  
  18.                   dprintk("rel_x error~~~:%s\n",strerror(errno));  
  19.          event.code = REL_Y;  
  20.          event.value = rel_y;  
  21.          gettimeofday(&event.time,0);  
  22.   
  23.          if( write(fd,&event,sizeof(event))!=sizeof(event))  
  24.                    dprintk("rel_y error~~~:%s\n",strerror(errno));  
  25.           //一定要刷新空的  
  26.          write(fd,&ev,sizeof(ev));  
  27. }  
 



鼠标和键盘文件打开方法:

C代码
  1. int fd_kbd; // /dev/input/event1  
  2. int fd_mouse; //dev/input/mouse2  
  3. fd_kbd = open("/dev/input/event1",O_RDWR);  
  4. if(fd_kbd<=0){  
  5.          printf("error open keyboard:%s\n",strerror(errno));  
  6. return -1;  
  7. }  
  8.   
  9. fd_mouse = open("/dev/input/event3",O_RDWR); //如果不行的话,那试试/dev/input/mice  
  10.   
  11. if(fd_mouse<=0){  
  12.          printf("error open mouse:%s\n",strerror(errno));  
  13. return -2;  
  14. }  
 


/dev/input/mice是鼠标的抽象,代表的是鼠标,也许是/dev/input/mouse,/dev/input/mouse1,或者空,

这个文件一直会存在。

这里你也许会问,我怎么知道/dev/input/eventX这些事件到底是什么事件阿,是鼠标还是键盘或者别的,

eventX代表的是所有输入设备(input核心)的事件,比如按键按下,或者鼠标移动,或者游戏遥控器等等,

在系统查看的方法是 cat /proc/bus/input/devices 就可以看到每个eventX是什么设备的事件了。

PS: 在GTK中用的话,可以参考下gtk_main_do_event这个函数

C代码
  1. static void simulate_key(GtkWidget *window,int keyval,int press)  
  2. {  
  3.          GdkEvent *event;  
  4.          GdkEventType type;  
  5.          if(press)  
  6.                   type = GDK_KEY_PRESS;  
  7.          else  
  8.                   type = GDK_KEY_RELEASE;  
  9.   
  10.          event = gdk_event_new(type);  
  11.          //event->key.send_event = TRUE;  
  12.          event->key.window = window->window; //一定要设置为主窗口  
  13.          event->key.keyval = keyval;  
  14.            
  15.          //FIXME:一定要加上这个,要不然容易出错  
  16.          g_object_ref(event->key.window);  
  17.          gdk_threads_enter();  
  18.          //FIXME: 记得用这个来发送事件  
  19.          gtk_main_do_event(event);  
  20.          gdk_threads_leave();  
  21.          gdk_event_free(event);  
  22.   
  23. }