input子系统四:输入事件是如何上报的

本文探讨Linux内核input子系统中输入事件的上报过程,详细解析input_event()函数、input_get_disposition()函数的角色,以及INPUT_PASS_TO_ALL、INPUT_PASS_TO_HANDLERS和INPUT_FLUSH等标志的含义。事件处理涉及event函数和handler的event函数,其中EV_ABS类型的事件由input_handle_abs_event处理。文章还提到多点上报协议typeA和typeB的区别,并指出input_sync()在事件上报流程中的作用,最终通过input_to_handler()将数据传递至用户空间。
摘要由CSDN通过智能技术生成

input子系统四:输入事件是如何上报的

我们在输入设备驱动中利用函数input_event()函数来上报事件,接下来我们就来看看,内核拿到我们上报的数据之后是如何继续上报到用户空间的


/**
 * input_event() - report new input event
 * @dev: device that generated the event
 * @type: type of the event
 * @code: event code
 * @value: value of the event
 *
 * This function should be used by drivers implementing various input
 * devices to report input events. See also input_inject_event().
 *
 * NOTE: input_event() may be safely used right after input device was
 * allocated with input_allocate_device(), even before it is registered
 * with input_register_device(), but the event will not reach any of the
 * input handlers. Such early invocation of input_event() may be used
 * to 'seed' initial state of a switch or initial position of absolute
 * axis, etc.
 */
void input_event(struct input_dev *dev,
		 unsigned int type, unsigned int code, int value)
{
   
	unsigned long flags;

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

--------------------------------------------------------------------

static void input_handle_event(struct input_dev *dev,
			       unsigned int type, unsigned int code, int value)
{
   
	int disposition = input_get_disposition(dev, type, code, &value);  //获取如何处理这个事件的方式

	if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
		add_input_randomness(type, code, value);
		
	if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
		dev->event(dev, type, code, value);

	if (!dev->vals)
		return;
	if (disposition & INPUT_PASS_TO_HANDLERS) {
   
		struct input_value *v;

		if (disposition & INPUT_SLOT) {
   
			v = &dev->vals[dev->num_vals++];
			v->type = EV_ABS;
			v->code = ABS_MT_SLOT;
			v->value = dev->mt->slot;
		}

		v = &dev->vals[dev->num_vals++];
		v->type = type;
		v->code = code;
		v->value = value;
	}

	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_get_disposition()有很大的关系,那就先来分析它


static int input_get_disposition(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值