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

来源:互联网 发布:阿里云域名优惠券 编辑:程序博客网 时间:2024/05/16 10:03

原文地址:http://hi.baidu.com/minyuanyang/blog/item/4c076209bc9b41a82fddd4fa.html

 


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


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

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

struct input_event {                                                          
    struct timeval time; //按键时间                                        
    __u16 type; //类型,在下面有定义                                    
    __u16 code; //要模拟成什么按键                                       
    __s32 value;//是按下还是释放                                          
};                                                                                       

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的正数值和负数值分别代表两个不同方向的值.

/*
* Event types
*/

#define EV_SYN            0x00
#define EV_KEY            0x01 //按键
#define EV_REL            0x02 //相对坐标(轨迹球)
#define EV_ABS            0x03 //绝对坐标
#define EV_MSC            0x04 //其他
#define EV_SW            0x05
#define EV_LED            0x11 //LED
#define EV_SND            0x12//声音
#define EV_REP            0x14//repeat
#define EV_FF            0x15
#define EV_PWR            0x16
#define EV_FF_STATUS        0x17
#define EV_MAX            0x1f
#define EV_CNT            (EV_MAX+1)

1。模拟按键输入
//其中0表示释放,1按键按下,2表示一直按下
//0 for EV_KEY for release, 1 for keypress and 2 for autorepeat.
void simulate_key(int fd,int value)
{
    struct input_event event;

    event.type = EV_KEY;
    //event.code = KEY_0;//要模拟成什么按键
    event.value = value;//是按下还是释放按键或者重复
    gettimeofday(&event.time,0);

    if(write(fd,&event,sizeof(event)) < 0){
        dprintk("simulate key error~~~/n");
        return ;
    }
}

2。模拟鼠标输入(轨迹球)
void simulate_mouse(int fd,char buf[4])
{
    int rel_x,rel_y;
    static struct input_event event,ev;

    //buf[0],buf[2],小于0则为左移,大于0则为右移
    //buf[1],buf[3],小于0则为下移,大于0则为上移
    dprintk("MOUSE TOUCH: x1=%d,y1=%d,x2=%d,y2=%d/n",buf[0],buf[1],buf[2],buf[3]);

    rel_x = (buf[0] + buf[2]) /2;
    rel_y = -(buf[1] + buf[3]) /2; //和我们的鼠标是相反的方向,所以取反

    event.type = EV_REL;

    event.code = REL_X;
    event.value = rel_x;
    gettimeofday(&event.time,0);
    if( write(fd,&event,sizeof(event))!=sizeof(event))
        dprintk("rel_x error~~~:%s/n",strerror(errno));

    event.code = REL_Y;
    event.value = rel_y;
    gettimeofday(&event.time,0);
    if( write(fd,&event,sizeof(event))!=sizeof(event))
        dprintk("rel_y error~~~:%s/n",strerror(errno));
   
    //一定要刷新空的
    write(fd,&ev,sizeof(ev));
}


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

int fd_kbd; // /dev/input/event1
int fd_mouse; //dev/input/mouse2

fd_kbd = open("/dev/input/event1",O_RDWR);
    if(fd_kbd<=0){
        printf("error open keyboard:%s/n",strerror(errno));
        return -1;
    }

fd_mouse = open("/dev/input/event3",O_RDWR); //如果不行的话,那试试/dev/input/mice
if(fd_mouse<=0){
           printf("error open mouse:%s/n",strerror(errno));
            return -2;
        }
}


/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这个函数

static void simulate_key(GtkWidget *window,int keyval,int press)
{
    GdkEvent *event;
    GdkEventType type;

    if(press)   
        type = GDK_KEY_PRESS;
    else
        type = GDK_KEY_RELEASE;

    event = gdk_event_new(type);
    //event->key.send_event = TRUE;
    event->key.window = window->window; //一定要设置为主窗口
    event->key.keyval = keyval;

    //FIXME:一定要加上这个,要不然容易出错
    g_object_ref(event->key.window);

    gdk_threads_enter();

    //FIXME: 记得用这个来发送事件
    gtk_main_do_event(event);

    gdk_threads_leave();
    gdk_event_free(event);
}


参考:
http://cache.baidu.comc?m=9f65cb4a8c8507ed4fece763104e953f484380146d94975439c3933fc23846000c27feed727458199487223a52f91d07b4a72b72350124b298c98849dbbb942d24892c23706bc40354c75cf28b102a8177ce4de8df0ee0cee733e3e4c5d3ae0a0896144f&p=882a975685cc42a934b4c23f4b47&user=baidu

Linux输入子系统分析
http://www.linuxdriver.cn/html/20079/113.htm

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 家庭版密钥专业版系统怎么办 win7应用程序不能启动怎么办 win7用户密码忘记了怎么办 win7用户密码忘了怎么办 windows开不了机怎么办 网卡被卸载了怎么办 win7注销黑屏了怎么办 w7密码忘了怎么办 笔记本电脑键盘进水了怎么办 笔记本键盘进水了怎么办 笔记本进水键盘失灵怎么办 win7进不了系统怎么办 电脑显示屏两边黑屏怎么办 win8关机关不了怎么办 win10没激活黑屏怎么办 忘了产品密钥怎么办 小马易贷逾期怎么办 10系统未激活怎么办 win10账户被停用怎么办 win7激活码无效怎么办 windows显示不是正版怎么办 优酷上传错误怎么办 盗版系统会黑屏怎么办 安装了盗版系统怎么办 电脑鼠标不好用怎么办 自己组装电脑系统怎么办 ie双击没反应怎么办 电脑系统删了怎么办 产品密钥不知道怎么办 电脑安装ae崩溃怎么办 升级win10要密钥怎么办 系统里没有中文怎么办 小马激活后黑屏怎么办 电脑变成英文了怎么办 3dsmax英文版怎么办 手机设置越南文怎么办 电脑没有dvd驱动器怎么办 w7副本不是正版怎么办 win7硬盘速度慢怎么办 光盘装不了系统怎么办 winxp忘记开机密码怎么办