Linux/Android——input_handler之evdev (四) 【转】

摘要:
如需要详查请直接与键盘生产厂商法人代表联系.挖井挑水无水表,不会网购无快递目录(?

转自:http://blog.csdn.net/u013491946/article/details/72638919

版权声明:免责声明: 本人在此发文(包括但不限于汉字、拼音、拉丁字母)均为随意敲击键盘所出,用于检验本人电脑键盘录入、屏幕显示的机械、光电性能,并不代表本人局部或全部同意、支持或者反对观点。如需要详查请直接与键盘生产厂商法人代表联系 .挖井挑水无水表,不会网购无快递

目录(?)[+]

在前文Linux/Android——input子系统核心 (三)中概括了总体的结构,以及介绍了input核心的职责,其中有说道注册input设备时会去匹配已有的事件处理器handler,

而这个handler也是存放在一个链表里面的,这里介绍下input子系统中的事件处理input_handler机制.


撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/42238377#t6


evdev:

/kernel/drivers/input下众多事件处理器handler其中的一个,可以看下源码/kernel/drivers/input/evdev.c中的模块init:

  1. staticintvoidreturn}


这个初始化就是往input核心中注册一个input_handler类型的evdev_handler,调用的是input.c提供的接口,input_handler结构前文有介绍,看下evdev_handler的赋值:

  1. staticstruct=evdev_event,
  2. =evdev_connect,
  3. =evdev_disconnect,
  4. =&evdev_fops,
  5. =EVDEV_MINOR_BASE,
  6. =,
  7. =evdev_ids,
  8. };


赋值各个函数指针!



input_register_handler:

可以看到上面的evdev handler 就是调用这个接口注册到input核心中的,同样evdev.c同目录下也还有其它的handler,有兴趣可以看看它们的init函数,都是会调用到这个接口去注册的.

  1. /**
  2. *input_register_handler-registeranewinputhandler
  3. *@handler:handlertoberegistered
  4. *
  5. *Thisfunctionregistersanewinputhandler(interface)forinput
  6. *devicesinthesystemandattachesittoallinputdevicesthat
  7. *arecompatiblewiththehandler.
  8. */intstructinput_handlerstructinput_devintifreturnifNULLif]){
  9. goto]=handler;
  10. outreturn}


input核心中保存的handler数组:

  1. staticstructinput_handler];


这是保存注册到input核心中的handler数组,因为在之前input注册的时候注册的字符设备主设备号为13.字符设备的次设备号为0~255,可以有256个设备,

这里后面会看到一个handler可以connect处理32个input设备,所以input体系中,最多拥有8个handler


这个匹配过程和上一篇中的过程是一样的,最后匹配上的话会调用匹配上的handler 中connect指针指向的函数.


另外可以注意的是evdev是匹配所有设备的,因为:

  1. staticconststruct=},
  2. };


如果没有特定的handler添加进handler链表,那么在匹配的时候,只要有这个evdev的handler,最后都会匹配到evdev,这个具体可以去看看上篇的匹配过程.

我这边调试的是usb触摸屏,所以用的是evdev的handler,下面看下evdev的connect.


evdev_connect:

注册的evdev_handler中connect指向的函数为evdev_connect:

  1. /*
  2. *Createnewevdevdevice.Notethatinputcoreserializescalls
  3. *toconnectanddisconnectsowedon'tneedtolockevdev_tablehere.
  4. */staticintstructinput_handlerstructinput_devconststructinput_device_ididstructevdevintintfor;minor<EVDEV_MINORS;minor++)
  5. ifbreakifreturn//可以看到这里evdevhandler匹配连接好的设备都以evdev类型存在这个evdev_table数组的,这个数组大小为32个,这就是我上面说到的,为什么只有8个handler//这里是判断evdev的32个位置中是否有空sizeofstruct
  6. ifreturn
  7. ,minor);
  8. true
  9. =input_get_device(dev);
  10. =dev_name(&evdev->dev);
  11. =handler;
  12. =evdev;
  13. =MKDEV(INPUT_MAJOR,EVDEV_MINOR_BASE+minor);
  14. =&input_class;
  15. =&dev->dev;
  16. =evdev_free;
  17. ifgoto
  18. ifgoto
  19. ifgotoreturn;
  20. err_cleanup_evdeverr_unregister_handleerr_free_evdevreturn}



evdev:

这里的evdev变量的结构如下:

  1. structint
  2. int
  3. struct
  4. struct__rcu
  5. struct
  6. structstructbool};



关于这个结构变量我的理解是抽象出来一个设备,代表一个input_dev与其匹配好的handler的组合(handle),可以看作提供给事件处理层的一个封装.


input_handle:

这个代表一个匹配成功的input dev和 handler组合,定义在input.h中,每个evdev中包含一个input_handle,并且注册到input核心中:

  1. /**
  2. *structinput_handle-linksinputdevicewithaninputhandler
  3. *@private:handler-specificdata
  4. *@open:countershowingwhetherthehandleis'open',i.e.shoulddeliver
  5. *eventsfromitsdevice
  6. *@name:namegiventothehandlebyhandlerthatcreatedit
  7. *@dev:inputdevicethehandleisattachedto
  8. *@handler:handlerthatworkswiththedevicethroughthishandle
  9. *@d_node:usedtoputthehandleondevice'slistofattachedhandles
  10. *@h_node:usedtoputthehandleonhandler'slistofhandlesfromwhich
  11. *itgetsevents
  12. */structvoidvoidprivate
  13. intconstcharcharstructinput_dev
  14. structinput_handler
  15. struct
  16. struct};

input_register_handle:

看看这个handle的注册,不要和handler搞混淆了,这不是一个概念~

  1. /**
  2. *input_register_handle-registeranewinputhandle
  3. *@handle:handletoregister
  4. *
  5. *Thisfunctionputsanewinputhandleontodevice's
  6. *andhandler'slistssothateventscanflowthrough
  7. *itonceitisopenedusinginput_open_device().
  8. *
  9. *Thisfunctionissupposedtobecalledfromhandler's
  10. *connect()method.
  11. */intstructinput_handlestructinput_handlerstructinput_dev
  12. *Filtersgototheheadofthelist,normalhandlers
  13. *tothetail.
  14. */ifelse//把这个handle的d_node加到对应input_dev的h_list链表里面//把这个handle的h_node加到对应input_handler的h_list链表里面}


这个注册是把handle 本身的链表加入到它自己的input_dev 以及 input_handler的h_list链表中,这样以后就可以通过h_list遍历到这个handle,

这样就实现了三者的绑定联系.



另外在evdev中还有个结构:


  1. structint
  2. int
  3. int
  4. structboolchar8structfasync_struct
  5. structevdev
  6. struct
  7. intstruct
  8. };


这个结构会在evdev被打开的时候 创建,这里关于evdev的初始以及在input系统中承接作用暂时介绍到这里,

前文Linux/Android——输入子系统input_event传递 (二) 中有记录从设备驱动传递上来的event是怎么到input核心,然后接着往上传递的,接下来就是用到evdev传递了.下篇介绍.

免责声明:文章转载自《Linux/Android——input_handler之evdev (四) 【转】》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用Postman或requests结合chromedriver模拟Selenium操作浏览器10491下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

查看linux硬盘使用率

df -h df命令是Linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息,命令格式: df -hl 显示格式为:  文件系统 容量 已用 可用 已用% 挂载点  filesystem Size Used Avail Use% Mounted on /dev/hda2 45G 19G 24G 44% / /dev/hda1 4...

后端开发工程师的开发环境配置(Vscode+C/Go/Python等)

前言         我是一名后端开发工程师,主要语言是C、Go、Python。早年做C开发的时候都是在windows下开发,一直使用的是soure insight,尤其是时隔多年更新的4.0版本解决了中文乱码等问题,用起来更是得心应手。后来转到Mac下开发,虽然可以用wine运行windows程序,但总感觉别扭,也是时候做一些新的尝试了。      ...

el-input的keyup事件的使用

使用el-input插件后直接使用keyup 是不生效的: 需要在@keyup事件后加上native,即@keyup.enter.native='(方法)': vue 监听键盘回车事件 @keyup.enter || @keyup.enter.native <input v-on:keyup.enter="submit"> <...

【tensorflow2.0】模型层layers

深度学习模型一般由各种模型层组合而成。 tf.keras.layers内置了非常丰富的各种功能的模型层。例如, layers.Dense,layers.Flatten,layers.Input,layers.DenseFeature,layers.Dropout layers.Conv2D,layers.MaxPooling2D,layers.Conv1D...

Linux多进程开发IV

1.共享内存。允许两个或多个进程共享物理内存的同一块区域(段)。 共享内存是进程用户空间的一部分,因此这种IPC机制需要更少的内核处理。一个进程将数据复制到共享内存中,那么这部分数据就会对其他所有共享同一个段的进程可用。 与管道等要求发送进程将数据从用户空间的缓冲区复制到内核内存和接收进程将数据从内核内存复制进用户空间的缓冲区的做法相比,这种IPC技术...

交叉编译工具链(详解)

交叉编译工具链  1、嵌入式开发模型-交叉开发     在嵌入式开发过程中有宿主机和目标机的角色之分:宿主机是执行编译、链接嵌入式软件的计算机;目标机是运行嵌入式软件的硬件平台。                在宿主机执行编译的流程如下:                   2、交叉编译工具链详解 参考: http://www.crifan.com/fi...