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

上传人:b****4 文档编号:4791699 上传时间:2022-12-09 格式:DOCX 页数:16 大小:21.87KB
下载 相关 举报
linux下如何模拟按键输入和模拟鼠标.docx_第1页
第1页 / 共16页
linux下如何模拟按键输入和模拟鼠标.docx_第2页
第2页 / 共16页
linux下如何模拟按键输入和模拟鼠标.docx_第3页
第3页 / 共16页
linux下如何模拟按键输入和模拟鼠标.docx_第4页
第4页 / 共16页
linux下如何模拟按键输入和模拟鼠标.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

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

《linux下如何模拟按键输入和模拟鼠标.docx》由会员分享,可在线阅读,更多相关《linux下如何模拟按键输入和模拟鼠标.docx(16页珍藏版)》请在冰豆网上搜索。

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

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

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中有定义,这个文件还定义了标准按键的编码等

structinput_event{

structtimevaltime;//按键时间

__u16type;//类型,在下面有定义

__u16code;//要模拟成什么按键

__s32value;//是按下还是释放

};

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

/*

*Eventtypes

*/

#defineEV_SYN0x00

#defineEV_KEY0x01//按键

#defineEV_REL0x02//相对坐标(轨迹球)

#defineEV_ABS0x03//绝对坐标

#defineEV_MSC0x04//其他

#defineEV_SW0x05

#defineEV_LED0x11//LED

#defineEV_SND0x12//声音

#defineEV_REP0x14//repeat

#defineEV_FF0x15

#defineEV_PWR0x16

#defineEV_FF_STATUS0x17

#defineEV_MAX0x1f

#defineEV_CNT(EV_MAX+1)

1。

模拟按键输入

//其中0表示释放,1按键按下,2表示一直按下

//0forEV_KEYforrelease,1forkeypressand2forautorepeat.

voidsimulate_key(intfd,intvalue)

{

structinput_eventevent;

event.type=EV_KEY;

//event.code=KEY_0;//要模拟成什么按键

event.value=value;//是按下还是释放按键或者重复

gettimeofday(&event.time,0);

if(write(fd,&event,sizeof(event))<0){

dprintk("simulatekeyerror~~~\n");

return;

}

}

2。

模拟鼠标输入(轨迹球)

voidsimulate_mouse(intfd,charbuf[4])

{

intrel_x,rel_y;

staticstructinput_eventevent,ev;

//buf[0],buf[2],小于0则为左移,大于0则为右移

//buf[1],buf[3],小于0则为下移,大于0则为上移

dprintk("MOUSETOUCH:

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_xerror~~~:

%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_yerror~~~:

%s\n",strerror(errno));

//一定要刷新空的

write(fd,&ev,sizeof(ev));

}

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

intfd_kbd;///dev/input/event1

intfd_mouse;//dev/input/mouse2

fd_kbd=open("/dev/input/event1",O_RDWR);

if(fd_kbd<=0){

printf("erroropenkeyboard:

%s\n",strerror(errno));

return-1;

}

fd_mouse=open("/dev/input/event3",O_RDWR);//如果不行的话,那试试/dev/input/mice

if(fd_mouse<=0){

printf("erroropenmouse:

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

staticvoidsimulate_key(GtkWidget*window,intkeyval,intpress)

{

GdkEvent*event;

GdkEventTypetype;

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);

}

kernel里input模块

input_dev结构:

structinput_dev{

   void*private;

   constchar*name;

   constchar*phys;

   constchar*uniq;

   structinput_idid;

   /*

   *根据各种输入信号的类型来建立类型为unsignedlong的数组,

   *数组的每1bit代表一种信号类型,

   *内核中会对其进行置位或清位操作来表示时间的发生和被处理.

   */

   unsignedlongevbit[NBITS(EV_MAX)];

   unsignedlongkeybit[NBITS(KEY_MAX)];

   unsignedlongrelbit[NBITS(REL_MAX)];

   unsignedlongabsbit[NBITS(ABS_MAX)];

   unsignedlongmscbit[NBITS(MSC_MAX)];

   unsignedlongledbit[NBITS(LED_MAX)];

   unsignedlongsndbit[NBITS(SND_MAX)];

   unsignedlongffbit[NBITS(FF_MAX)];

   unsignedlongswbit[NBITS(SW_MAX)];

   .........................................

};

/**

*input_set_capability-markdeviceascapableofacertainevent

*@dev:

devicethatiscapableofemittingoracceptingevent

*@type:

typeoftheevent(EV_KEY,EV_REL,etc...)

*@code:

eventcode

*

*Inadditiontosettingupcorrespondingbitinappropriatecapability

*bitmapthefunctionalsoadjustsdev->evbit.

*/

/*记录本设备对于哪些事件感兴趣(对其进行处理)*/

voidinput_set_capability(structinput_dev*dev,unsignedinttype,unsignedintcode)

{

   switch(type){

   caseEV_KEY:

      __set_bit(code,dev->keybit);//比如按键,应该对哪些键值的按键进行处理(对于其它按键不予理睬)

      break;

   caseEV_REL:

      __set_bit(code,dev->relbit);

      break;

   caseEV_ABS:

      __set_bit(code,dev->absbit);

      break;

   caseEV_MSC:

      __set_bit(code,dev->mscbit);

      break;

   caseEV_SW:

      __set_bit(code,dev->swbit);

      break;

   caseEV_LED:

      __set_bit(code,dev->ledbit);

      break;

   caseEV_SND:

      __set_bit(code,dev->sndbit);

      break;

   caseEV_FF:

      __set_bit(code,dev->ffbit);

      break;

   default:

      printk(KERN_ERR

         "input_set_capability:

unknowntype%u(code%u)\n",

         type,code);

      dump_stack();

      return;

   }

   __set_bit(type,dev->evbit);//感觉和前面重复了(前面一经配置过一次了)

}

EXPORT_SYMBOL(input_set_capability);

staticirqreturn_tgpio_keys_isr(intirq,void*dev_id)

{

       inti;

       structplatform_device*pdev=dev_id;

       structgpio_keys_platform_data*pdata=pdev->dev.platform_data;

       structinput_dev*input=platform_get_drvdata(pdev);

       for(i=0;inbuttons;i++){

               structgpio_keys_button*button=&pdata->buttons[i];

               intgpio=button->gpio;

               if(irq==gpio_to_irq(gpio)){//判断哪个键被按了?

                       unsignedinttype=button->type?

:

EV_KEY;

                       intstate=(gpio_get_value(gpio)?

1:

0)^button->active_low;//记录按键状态

                       input_event(input,type,button->code,!

!

state);//汇报输入事件

                       input_sync(input);//等待输入事件处理完成

               }

       }

       returnIRQ_HANDLED;

}

/*

*input_event()-reportnewinputevent

*@dev:

devicethatgeneratedtheevent

*@type:

typeoftheevent

*@code:

eventcode

*@value:

valueoftheevent

*

*Thisfunctionshouldbeusedbydriversimplementingvariousinputdevices

*Seealsoinput_inject_event()

*/

voidinput_event(structinput_dev*dev,unsignedinttype,unsignedintcode,intvalue)

{

   structinput_handle*handle;

   if(type>EV_MAX||!

test_bit(type,dev->evbit))//首先判断该事件类型是否有效且为该设备所接受

      return;

   add_input_randomness(type,code,value);

   switch(type){

      caseEV_SYN:

         switch(code){

            caseSYN_CONFIG:

               if(dev->event)

                  dev->event(dev,type,code,value);

               break;

            caseSYN_REPORT:

               if(dev->sync)

                  return;

               dev->sync=1;

               break;

         }

         break;

      caseEV_KEY:

         /*

         *这里需要满足几个条件:

         *1:

键值有效(不超出定义的键值的有效范围)

         *2:

键值为设备所能接受(属于该设备所拥有的键值范围)

         *3:

按键状态改变了

         */

         if(code>KEY_MAX||!

test_bit(code,dev->keybit)||!

!

test_bit(code,dev->key)==value)

            return;

         if(value==2)

            break;

         change_bit(code,dev->key);//改变对应按键的状态

         /*如果你希望按键未释放的时候不断汇报按键事件的话需要以下这个(在简单的gpio_keys驱动中不需要这个,暂时不去分析)*/

         if(test_bit(EV_REP,dev->evbit)&&dev->rep[REP_PERIOD]&&dev->rep[REP_DELAY]&&dev->timer.data&&value){

            dev->repeat_key=code;

            mod_timer(&dev->timer,jiffies+msecs_to_jiffies(dev->rep[REP_DELAY]));

         }

         break;

........................................................

   if(type!

=EV_SYN)

      dev->sync=0;

   if(dev->grab)

      dev->grab->handler->event(dev->grab,type,code,value);

   else

      /*

      *循环调用所有处理该设备的handle(event,mouse,ts,joy等),

      *如果有进程打开了这些handle(进行读写),则调用其对应的event接口向气汇报该输入事件.

      */

      list_for_each_entry(handle,&dev->h_list,d_node)

         if(handle->open)

            handle->handler->event(handle,type,code,value);

}

EXPORT_SYMBOL(input_event);

event层对于input层报告的这个键盘输入事件的处理:

drivers/input/evdev.c:

staticstructinput_handlerevdev_handler={

       .event=       evdev_event,

       .connect=     evdev_connect,

       .disconnect=  evdev_disconnect,

       .fops=        &evdev_fops,

       .minor=       EVDEV_MINOR_BASE,

       .name=        "evdev",

       .id_table=    evdev_ids,

};

Linux有自己的input子系统,可以统一管理鼠标和键盘事件。

基于输入子系统实现的uinput可以方便的在用户空间模拟鼠标和键盘事件。

当然,也可以自己造轮子,做一个字符设备接收用户输入,根据输入,投递input事件。

还有一种方式就是直接往evnent里写入数据,都可以达到控制鼠标键盘的功能。

本篇文章就是演示直接写入event的方法。

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

structinput_event{

   structtimevaltime; //按键时间

   __u16type;//类型,在下面有定义

   __u16code;//要模拟成什么按键

   __s32value;//是按下还是释放

};

code:

事件的代码.如果事件的类型代码是EV_KEY,该代码code为设备键盘代码.代码植0~127为键盘上的按键代码,0x110~0x116为鼠标上按键代码,其中0x110(BTN_LEFT)为鼠标左键,0x111(BTN_RIGHT)为鼠标右键,0x112(BTN_MIDDLE)为鼠标中键.其它代码含义请参看include/linux

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1