2174 lines · 52.3 KB · C
RawDownload
/* * The input core * * Copyright (c) 1999-2002 Vojtech Pavlik */ /* * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. */ #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt #include <linux/init.h>#include <linux/types.h>#include <linux/input/mt.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/random.h>#include <linux/major.h>#include <linux/proc_fs.h>#include <linux/sched.h>#include <linux/seq_file.h>#include <linux/poll.h>#include <linux/device.h>#include <linux/mutex.h>#include <linux/rcupdate.h>#include "input-compat.h" MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");MODULE_DESCRIPTION("Input core");MODULE_LICENSE("GPL"); #define INPUT_DEVICES	256 static LIST_HEAD(input_dev_list);static LIST_HEAD(input_handler_list); /* * input_mutex protects access to both input_dev_list and input_handler_list. * This also causes input_[un]register_device and input_[un]register_handler * be mutually exclusive which simplifies locking in drivers implementing * input handlers. */static DEFINE_MUTEX(input_mutex); static struct input_handler *input_table[8]; static inline int is_event_supported(unsigned int code,				     unsigned long *bm, unsigned int max){	return code <= max && test_bit(code, bm);} static int input_defuzz_abs_event(int value, int old_val, int fuzz){	if (fuzz) {		if (value > old_val - fuzz / 2 && value < old_val + fuzz / 2)			return old_val; 		if (value > old_val - fuzz && value < old_val + fuzz)			return (old_val * 3 + value) / 4; 		if (value > old_val - fuzz * 2 && value < old_val + fuzz * 2)			return (old_val + value) / 2;	} 	return value;} /* * Pass event first through all filters and then, if event has not been * filtered out, through all open handles. This function is called with * dev->event_lock held and interrupts disabled. */static void input_pass_event(struct input_dev *dev,			     unsigned int type, unsigned int code, int value){	struct input_handler *handler;	struct input_handle *handle; 	rcu_read_lock(); 	handle = rcu_dereference(dev->grab);	if (handle)		handle->handler->event(handle, type, code, value);	else {		bool filtered = false; 		list_for_each_entry_rcu(handle, &dev->h_list, d_node) {			if (!handle->open)				continue; 			handler = handle->handler;			if (!handler->filter) {				if (filtered)					break; 				handler->event(handle, type, code, value); 			} else if (handler->filter(handle, type, code, value))				filtered = true;		}	} 	rcu_read_unlock();} /* * Generate software autorepeat event. Note that we take * dev->event_lock here to avoid racing with input_event * which may cause keys get "stuck". */static void input_repeat_key(unsigned long data){	struct input_dev *dev = (void *) data;	unsigned long flags; 	spin_lock_irqsave(&dev->event_lock, flags); 	if (test_bit(dev->repeat_key, dev->key) &&	    is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { 		input_pass_event(dev, EV_KEY, dev->repeat_key, 2); 		if (dev->sync) {			/*			 * Only send SYN_REPORT if we are not in a middle			 * of driver parsing a new hardware packet.			 * Otherwise assume that the driver will send			 * SYN_REPORT once it's done.			 */			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);		} 		if (dev->rep[REP_PERIOD])			mod_timer(&dev->timer, jiffies +					msecs_to_jiffies(dev->rep[REP_PERIOD]));	} 	spin_unlock_irqrestore(&dev->event_lock, flags);} static void input_start_autorepeat(struct input_dev *dev, int code){	if (test_bit(EV_REP, dev->evbit) &&	    dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&	    dev->timer.data) {		dev->repeat_key = code;		mod_timer(&dev->timer,			  jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));	}} static void input_stop_autorepeat(struct input_dev *dev){	del_timer(&dev->timer);} #define INPUT_IGNORE_EVENT	0#define INPUT_PASS_TO_HANDLERS	1#define INPUT_PASS_TO_DEVICE	2#define INPUT_PASS_TO_ALL	(INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) static int input_handle_abs_event(struct input_dev *dev,				  unsigned int code, int *pval){	bool is_mt_event;	int *pold; 	if (code == ABS_MT_SLOT) {		/*		 * "Stage" the event; we'll flush it later, when we		 * get actual touch data.		 */		if (*pval >= 0 && *pval < dev->mtsize)			dev->slot = *pval; 		return INPUT_IGNORE_EVENT;	} 	is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST; 	if (!is_mt_event) {		pold = &dev->absinfo[code].value;	} else if (dev->mt) {		struct input_mt_slot *mtslot = &dev->mt[dev->slot];		pold = &mtslot->abs[code - ABS_MT_FIRST];	} else {		/*		 * Bypass filtering for multi-touch events when		 * not employing slots.		 */		pold = NULL;	} 	if (pold) {		*pval = input_defuzz_abs_event(*pval, *pold,						dev->absinfo[code].fuzz);		if (*pold == *pval)			return INPUT_IGNORE_EVENT; 		*pold = *pval;	} 	/* Flush pending "slot" event */	if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {		input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);		input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);	} 	return INPUT_PASS_TO_HANDLERS;} static void input_handle_event(struct input_dev *dev,			       unsigned int type, unsigned int code, int value){	int disposition = INPUT_IGNORE_EVENT; 	switch (type) { 	case EV_SYN:		switch (code) {		case SYN_CONFIG:			disposition = INPUT_PASS_TO_ALL;			break; 		case SYN_REPORT:			if (!dev->sync) {				dev->sync = true;				disposition = INPUT_PASS_TO_HANDLERS;			}			break;		case SYN_MT_REPORT:			dev->sync = false;			disposition = INPUT_PASS_TO_HANDLERS;			break;		}		break; 	case EV_KEY:		if (is_event_supported(code, dev->keybit, KEY_MAX) &&		    !!test_bit(code, dev->key) != value) { 			if (value != 2) {				__change_bit(code, dev->key);				if (value)					input_start_autorepeat(dev, code);				else					input_stop_autorepeat(dev);			} 			disposition = INPUT_PASS_TO_HANDLERS;		}		break; 	case EV_SW:		if (is_event_supported(code, dev->swbit, SW_MAX) &&		    !!test_bit(code, dev->sw) != value) { 			__change_bit(code, dev->sw);			disposition = INPUT_PASS_TO_HANDLERS;		}		break; 	case EV_ABS:		if (is_event_supported(code, dev->absbit, ABS_MAX))			disposition = input_handle_abs_event(dev, code, &value); 		break; 	case EV_REL:		if (is_event_supported(code, dev->relbit, REL_MAX) && value)			disposition = INPUT_PASS_TO_HANDLERS; 		break; 	case EV_MSC:		if (is_event_supported(code, dev->mscbit, MSC_MAX))			disposition = INPUT_PASS_TO_ALL; 		break; 	case EV_LED:		if (is_event_supported(code, dev->ledbit, LED_MAX) &&		    !!test_bit(code, dev->led) != value) { 			__change_bit(code, dev->led);			disposition = INPUT_PASS_TO_ALL;		}		break; 	case EV_SND:		if (is_event_supported(code, dev->sndbit, SND_MAX)) { 			if (!!test_bit(code, dev->snd) != !!value)				__change_bit(code, dev->snd);			disposition = INPUT_PASS_TO_ALL;		}		break; 	case EV_REP:		if (code <= REP_MAX && value >= 0 && dev->rep[code] != value) {			dev->rep[code] = value;			disposition = INPUT_PASS_TO_ALL;		}		break; 	case EV_FF:		if (value >= 0)			disposition = INPUT_PASS_TO_ALL;		break; 	case EV_PWR:		disposition = INPUT_PASS_TO_ALL;		break;	} 	if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)		dev->sync = false; 	if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)		dev->event(dev, type, code, value); 	if (disposition & INPUT_PASS_TO_HANDLERS)		input_pass_event(dev, type, code, value);} /** * 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);		add_input_randomness(type, code, value);		input_handle_event(dev, type, code, value);		spin_unlock_irqrestore(&dev->event_lock, flags);	}}EXPORT_SYMBOL(input_event); /** * input_inject_event() - send input event from input handler * @handle: input handle to send event through * @type: type of the event * @code: event code * @value: value of the event * * Similar to input_event() but will ignore event if device is * "grabbed" and handle injecting event is not the one that owns * the device. */void input_inject_event(struct input_handle *handle,			unsigned int type, unsigned int code, int value){	struct input_dev *dev = handle->dev;	struct input_handle *grab;	unsigned long flags; 	if (is_event_supported(type, dev->evbit, EV_MAX)) {		spin_lock_irqsave(&dev->event_lock, flags); 		rcu_read_lock();		grab = rcu_dereference(dev->grab);		if (!grab || grab == handle)			input_handle_event(dev, type, code, value);		rcu_read_unlock(); 		spin_unlock_irqrestore(&dev->event_lock, flags);	}}EXPORT_SYMBOL(input_inject_event); /** * input_alloc_absinfo - allocates array of input_absinfo structs * @dev: the input device emitting absolute events * * If the absinfo struct the caller asked for is already allocated, this * functions will not do anything. */void input_alloc_absinfo(struct input_dev *dev){	if (!dev->absinfo)		dev->absinfo = kcalloc(ABS_CNT, sizeof(struct input_absinfo),					GFP_KERNEL); 	WARN(!dev->absinfo, "%s(): kcalloc() failed?\n", __func__);}EXPORT_SYMBOL(input_alloc_absinfo); void input_set_abs_params(struct input_dev *dev, unsigned int axis,			  int min, int max, int fuzz, int flat){	struct input_absinfo *absinfo; 	input_alloc_absinfo(dev);	if (!dev->absinfo)		return; 	absinfo = &dev->absinfo[axis];	absinfo->minimum = min;	absinfo->maximum = max;	absinfo->fuzz = fuzz;	absinfo->flat = flat; 	dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);}EXPORT_SYMBOL(input_set_abs_params);  /** * input_grab_device - grabs device for exclusive use * @handle: input handle that wants to own the device * * When a device is grabbed by an input handle all events generated by * the device are delivered only to this handle. Also events injected * by other input handles are ignored while device is grabbed. */int input_grab_device(struct input_handle *handle){	struct input_dev *dev = handle->dev;	int retval; 	retval = mutex_lock_interruptible(&dev->mutex);	if (retval)		return retval; 	if (dev->grab) {		retval = -EBUSY;		goto out;	} 	rcu_assign_pointer(dev->grab, handle);  out:	mutex_unlock(&dev->mutex);	return retval;}EXPORT_SYMBOL(input_grab_device); static void __input_release_device(struct input_handle *handle){	struct input_dev *dev = handle->dev; 	if (dev->grab == handle) {		rcu_assign_pointer(dev->grab, NULL);		/* Make sure input_pass_event() notices that grab is gone */		synchronize_rcu(); 		list_for_each_entry(handle, &dev->h_list, d_node)			if (handle->open && handle->handler->start)				handle->handler->start(handle);	}} /** * input_release_device - release previously grabbed device * @handle: input handle that owns the device * * Releases previously grabbed device so that other input handles can * start receiving input events. Upon release all handlers attached * to the device have their start() method called so they have a change * to synchronize device state with the rest of the system. */void input_release_device(struct input_handle *handle){	struct input_dev *dev = handle->dev; 	mutex_lock(&dev->mutex);	__input_release_device(handle);	mutex_unlock(&dev->mutex);}EXPORT_SYMBOL(input_release_device); /** * input_open_device - open input device * @handle: handle through which device is being accessed * * This function should be called by input handlers when they * want to start receive events from given input device.

Lines 1–500 of 2174.