三 核心层
Handler与device的匹配是在下面函数完成。
static int input_attach_handler(structinput_dev *dev, struct input_handler *handler)
{………
id= input_match_device(handler, dev);
//调用 input_match_device()函数匹配 handler->>id_table 和 dev->id 中的数据。如果不成//功则返回。handle->id_table 也是一个 input_device_id 类型的指针,其表示驱动支持的设备//列表。
………
error= handler->connect(handler, dev, id);
//如果匹配成功,则调用 handler->connect()函数将 handler 与 input_dev 连接起来。
// 在connect() 中会调用input_register_handle,而这些都需要handler的注册。
………
}
input_event()函数用来向输入子系统报告输入设备产生的事件。 该函数的第 1 个参数是产生事件的输入设备,第2个参数是事件类型,例如key,abs等。第3个参数是产生的事件,第4个参数是事件的值。
需要注意的是, 第3个参数可以取类似 BTN_0、 BTN_1、BTN_LEFT、BTN_RIGHT 等值,这些键值被定义在include/linux/input.h 文件中。
第2个参数取值如下:
(1). #defineEV_SYN 0x00 /*表示设备支持所有的事件*/
(2). #defineEV_KEY 0x01 /*键盘或者按键,表示一个键码*/
(3). #defineEV_REL 0x02 /*鼠标设备,表示一个相对的光标位置结果*/
(4). #defineEV_ABS 0x03 /*手写板产生的值,其是一个绝对整数值*/
(5). #defineEV_MSC 0x04 /*其他类型*/
(6). #defineEV_LED 0x11 /*LED 灯设备*/
(7). #defineEV_SND 0x12 /*蜂鸣器,输入声音*/
(8). #defineEV_REP 0x14 /*允许重复按键类型*/
(9). #defineEV_PWR 0x16 /*电源管理事件*/
当第3个参数为按键时,第4个参数表示按键的状态,value 值为 0 表示按键释放,非 0 表示按键按下。
voidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, intvalue)
{
if (is_event_supported(type,dev->evbit, EV_MAX)) {//检查事件的合法性
spin_lock_irqsave(&dev->event_lock,flags);
input_handle_event(dev,type, code, value);//完成上报事件的功能
spin_unlock_irqrestore(&dev->event_lock,flags);
}
}
Input_report_key(),input_report_abs()等都是通过调用input_event()上报数据,仅仅是事件类型不同。
Input_event()函数通过input_handle_event()上传事件,其参数与input_event()的相同,并且顺序相同。该函数首先获得事件处理方式disposition,其取值如下:
#define INPUT_IGNORE_EVENT 0 //忽略该事件
#define INPUT_PASS_TO_HANDLERS 1 //事件传给handler处理
#define INPUT_PASS_TO_DEVICE 2 //事件传给device处理
#define INPUT_SLOT 4
#define INPUT_FLUSH 8
#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)//即传给handler也要传给device处理。
然后根据code和type给input_value *v赋值,最后通过input_pass_values()传给相关函数。即input_pass_values()最终完成上传事件的功能。
static void input_handle_event(structinput_dev *dev, unsigned int type, unsigned int code, int value)
{………
disposition= input_get_disposition(dev, type, code, value);//获得处理方式
………
if((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
dev->event(dev, type, code, value);//device处理
………
if (disposition & INPUT_FLUSH) {
if(dev->num_vals >= 2)
input_pass_values(dev, dev->vals, dev->num_vals);//传给相应函数
dev->num_vals= 0;
}else if (dev->num_vals >= dev->max_vals - 2) {
dev->vals[dev->num_vals++]= input_value_sync;
input_pass_values(dev,dev->vals, dev->num_vals);
dev->num_vals= 0;
}
}
input_pass_values()把事件传递给相应的handler,调用不同的handler处理函数。其调用handler_event的统一接口input_to_handler()
static void input_pass_values(structinput_dev *dev, struct input_value *vals, unsigned int count)
{………
if(handle) {
count= input_to_handler(handle, vals, count);//把事件类型、值等传给handler接口
}else {
list_for_each_entry_rcu(handle,&dev->h_list, d_node)
if(handle->open)
count= input_to_handler(handle, vals, count);
}
………
}
input_to_handler()调用handler->events()和handler->event(),不同的handler,handler->event()函数不同,这样input_event()就把事件上报给device或handler处理了,整个inputcore层的工作完成了。具体的处理是handler做的事情。
static unsigned int input_to_handler(structinput_handle *handle,
structinput_value *vals, unsigned int count)
{
………
for(v = vals; v != vals + count; v++) {
if(handler->filter && handler->filter(handle,v->type, v->code, v->value))
………
}
………
if(handler->events)
handler->events(handle, vals, count);
elseif (handler->event)
for(v = vals; v != end; v++)
handler->event(handle, v->type, v->code,v->value);
……..
}