转自: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:
这个初始化就是往input核心中注册一个input_handler类型的evdev_handler,调用的是input.c提供的接口,input_handler结构前文有介绍,看下evdev_handler的赋值:
-
staticstruct
= evdev_event,
-
= evdev_connect,
-
= evdev_disconnect,
-
= &evdev_fops,
-
= EVDEV_MINOR_BASE,
-
= ,
-
= evdev_ids,
-
};
赋值各个函数指针!
input_register_handler:
可以看到上面的evdev handler 就是调用这个接口注册到input核心中的,同样evdev.c同目录下也还有其它的handler,有兴趣可以看看它们的init函数,都是会调用到这个接口去注册的.
-
/**
-
* input_register_handler - register a new input handler
-
* @handler: handler to be registered
-
*
-
* This function registers a new input handler (interface) for input
-
* devices in the system and attaches it to all input devices that
-
* are compatible with the handler.
-
*/
intstructinput_handler
structinput_dev
int
if
return
ifNULL
if]) {
-
goto
] = handler;
-
-
-
out
return
}
input核心中保存的handler数组:
-
staticstructinput_handler];
这是保存注册到input核心中的handler数组,因为在之前input注册的时候注册的字符设备主设备号为13.字符设备的次设备号为0~255,可以有256个设备,
这里后面会看到一个handler可以connect处理32个input设备,所以input体系中,最多拥有8个handler
这个匹配过程和上一篇中的过程是一样的,最后匹配上的话会调用匹配上的handler 中connect指针指向的函数.
另外可以注意的是evdev是匹配所有设备的,因为:
-
staticconststruct
= },
-
-
};
如果没有特定的handler添加进handler链表,那么在匹配的时候,只要有这个evdev的handler,最后都会匹配到evdev,这个具体可以去看看上篇的匹配过程.
我这边调试的是usb触摸屏,所以用的是evdev的handler,下面看下evdev的connect.
evdev_connect:
注册的evdev_handler中connect指向的函数为evdev_connect:
-
/*
-
* Create new evdev device. Note that input core serializes calls
-
* to connect and disconnect so we don't need to lock evdev_table here.
-
*/
staticintstructinput_handlerstructinput_dev
conststructinput_device_idid
structevdev
int
int
for; minor < EVDEV_MINORS; minor++)
-
if
break
if
return
// 可以看到这里evdev handler匹配连接好的设备都以evdev 类型存在这个evdev_table数组的,这个数组大小为32个,这就是我上面说到的,为什么只有8个handler
//这里是判断evdev的32个位置中是否有空
sizeofstruct
-
if
return
-
, minor);
-
true
-
= input_get_device(dev);
-
= dev_name(&evdev->dev);
-
= handler;
-
= evdev;
-
= MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
-
= &input_class;
-
= &dev->dev;
-
= evdev_free;
-
-
if
goto
-
if
goto
-
if
goto
return;
-
err_cleanup_evdev
err_unregister_handle
err_free_evdev
return
}
evdev:
这里的evdev变量的结构如下:
-
struct
int
-
int
-
struct
-
-
struct__rcu
-
struct
-
-
struct
struct
bool
};
关于这个结构变量我的理解是抽象出来一个设备,代表一个input_dev与其匹配好的handler的组合(handle),可以看作提供给事件处理层的一个封装.
input_handle:
这个代表一个匹配成功的input dev和 handler组合,定义在input.h中,每个evdev中包含一个input_handle,并且注册到input核心中:
-
/**
-
* struct input_handle - links input device with an input handler
-
* @private: handler-specific data
-
* @open: counter showing whether the handle is 'open', i.e. should deliver
-
* events from its device
-
* @name: name given to the handle by handler that created it
-
* @dev: input device the handle is attached to
-
* @handler: handler that works with the device through this handle
-
* @d_node: used to put the handle on device's list of attached handles
-
* @h_node: used to put the handle on handler's list of handles from which
-
* it gets events
-
*/
struct
voidvoidprivate
-
int
constcharchar
structinput_dev
-
structinput_handler
-
struct
-
struct
};
input_register_handle:
看看这个handle的注册,不要和handler搞混淆了,这不是一个概念~
-
/**
-
* input_register_handle - register a new input handle
-
* @handle: handle to register
-
*
-
* This function puts a new input handle onto device's
-
* and handler's lists so that events can flow through
-
* it once it is opened using input_open_device().
-
*
-
* This function is supposed to be called from handler's
-
* connect() method.
-
*/
intstructinput_handle
structinput_handler
structinput_dev
-
* Filters go to the head of the list, normal handlers
-
* to the tail.
-
*/
if
else
//把这个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中还有个结构:
-
struct
int
-
int
-
int
-
-
struct
bool
char8
structfasync_struct
-
structevdev
-
struct
-
int
struct
-
};
这个结构会在evdev被打开的时候 创建,这里关于evdev的初始以及在input系统中承接作用暂时介绍到这里,
前文 Linux/Android——输入子系统input_event传递
(二) 中有记录从设备驱动传递上来的event是怎么到input核心,然后接着往上传递的,接下来就是用到evdev传递了.下篇介绍.