⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 input.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
}static int input_default_setkeycode(struct input_dev *dev,				    int scancode, int keycode){	int old_keycode;	int i;	if (scancode < 0 || scancode >= dev->keycodemax)		return -EINVAL;	if (keycode < 0 || keycode > KEY_MAX)		return -EINVAL;	if (!dev->keycodesize)		return -EINVAL;	if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))		return -EINVAL;	switch (dev->keycodesize) {		case 1: {			u8 *k = (u8 *)dev->keycode;			old_keycode = k[scancode];			k[scancode] = keycode;			break;		}		case 2: {			u16 *k = (u16 *)dev->keycode;			old_keycode = k[scancode];			k[scancode] = keycode;			break;		}		default: {			u32 *k = (u32 *)dev->keycode;			old_keycode = k[scancode];			k[scancode] = keycode;			break;		}	}	clear_bit(old_keycode, dev->keybit);	set_bit(keycode, dev->keybit);	for (i = 0; i < dev->keycodemax; i++) {		if (input_fetch_keycode(dev, i) == old_keycode) {			set_bit(old_keycode, dev->keybit);			break; /* Setting the bit twice is useless, so break */		}	}	return 0;}#define MATCH_BIT(bit, max) \		for (i = 0; i < BITS_TO_LONGS(max); i++) \			if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \				break; \		if (i != BITS_TO_LONGS(max)) \			continue;static const struct input_device_id *input_match_device(const struct input_device_id *id,							struct input_dev *dev){	int i;	for (; id->flags || id->driver_info; id++) {		if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)			if (id->bustype != dev->id.bustype)				continue;		if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)			if (id->vendor != dev->id.vendor)				continue;		if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)			if (id->product != dev->id.product)				continue;		if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)			if (id->version != dev->id.version)				continue;		MATCH_BIT(evbit,  EV_MAX);		MATCH_BIT(keybit, KEY_MAX);		MATCH_BIT(relbit, REL_MAX);		MATCH_BIT(absbit, ABS_MAX);		MATCH_BIT(mscbit, MSC_MAX);		MATCH_BIT(ledbit, LED_MAX);		MATCH_BIT(sndbit, SND_MAX);		MATCH_BIT(ffbit,  FF_MAX);		MATCH_BIT(swbit,  SW_MAX);		return id;	}	return NULL;}static int input_attach_handler(struct input_dev *dev, struct input_handler *handler){	const struct input_device_id *id;	int error;	if (handler->blacklist && input_match_device(handler->blacklist, dev))		return -ENODEV;	id = input_match_device(handler->id_table, dev);	if (!id)		return -ENODEV;	error = handler->connect(handler, dev, id);	if (error && error != -ENODEV)		printk(KERN_ERR			"input: failed to attach handler %s to device %s, "			"error: %d\n",			handler->name, kobject_name(&dev->dev.kobj), error);	return error;}#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry *proc_bus_input_dir;static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait);static int input_devices_state;static inline void input_wakeup_procfs_readers(void){	input_devices_state++;	wake_up(&input_devices_poll_wait);}static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait){	int state = input_devices_state;	poll_wait(file, &input_devices_poll_wait, wait);	if (state != input_devices_state)		return POLLIN | POLLRDNORM;	return 0;}static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos){	if (mutex_lock_interruptible(&input_mutex))		return NULL;	return seq_list_start(&input_dev_list, *pos);}static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos){	return seq_list_next(v, &input_dev_list, pos);}static void input_devices_seq_stop(struct seq_file *seq, void *v){	mutex_unlock(&input_mutex);}static void input_seq_print_bitmap(struct seq_file *seq, const char *name,				   unsigned long *bitmap, int max){	int i;	for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)		if (bitmap[i])			break;	seq_printf(seq, "B: %s=", name);	for (; i >= 0; i--)		seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : "");	seq_putc(seq, '\n');}static int input_devices_seq_show(struct seq_file *seq, void *v){	struct input_dev *dev = container_of(v, struct input_dev, node);	const char *path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);	struct input_handle *handle;	seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",		   dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);	seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : "");	seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : "");	seq_printf(seq, "S: Sysfs=%s\n", path ? path : "");	seq_printf(seq, "U: Uniq=%s\n", dev->uniq ? dev->uniq : "");	seq_printf(seq, "H: Handlers=");	list_for_each_entry(handle, &dev->h_list, d_node)		seq_printf(seq, "%s ", handle->name);	seq_putc(seq, '\n');	input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX);	if (test_bit(EV_KEY, dev->evbit))		input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX);	if (test_bit(EV_REL, dev->evbit))		input_seq_print_bitmap(seq, "REL", dev->relbit, REL_MAX);	if (test_bit(EV_ABS, dev->evbit))		input_seq_print_bitmap(seq, "ABS", dev->absbit, ABS_MAX);	if (test_bit(EV_MSC, dev->evbit))		input_seq_print_bitmap(seq, "MSC", dev->mscbit, MSC_MAX);	if (test_bit(EV_LED, dev->evbit))		input_seq_print_bitmap(seq, "LED", dev->ledbit, LED_MAX);	if (test_bit(EV_SND, dev->evbit))		input_seq_print_bitmap(seq, "SND", dev->sndbit, SND_MAX);	if (test_bit(EV_FF, dev->evbit))		input_seq_print_bitmap(seq, "FF", dev->ffbit, FF_MAX);	if (test_bit(EV_SW, dev->evbit))		input_seq_print_bitmap(seq, "SW", dev->swbit, SW_MAX);	seq_putc(seq, '\n');	kfree(path);	return 0;}static struct seq_operations input_devices_seq_ops = {	.start	= input_devices_seq_start,	.next	= input_devices_seq_next,	.stop	= input_devices_seq_stop,	.show	= input_devices_seq_show,};static int input_proc_devices_open(struct inode *inode, struct file *file){	return seq_open(file, &input_devices_seq_ops);}static const struct file_operations input_devices_fileops = {	.owner		= THIS_MODULE,	.open		= input_proc_devices_open,	.poll		= input_proc_devices_poll,	.read		= seq_read,	.llseek		= seq_lseek,	.release	= seq_release,};static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos){	if (mutex_lock_interruptible(&input_mutex))		return NULL;	seq->private = (void *)(unsigned long)*pos;	return seq_list_start(&input_handler_list, *pos);}static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos){	seq->private = (void *)(unsigned long)(*pos + 1);	return seq_list_next(v, &input_handler_list, pos);}static void input_handlers_seq_stop(struct seq_file *seq, void *v){	mutex_unlock(&input_mutex);}static int input_handlers_seq_show(struct seq_file *seq, void *v){	struct input_handler *handler = container_of(v, struct input_handler, node);	seq_printf(seq, "N: Number=%ld Name=%s",		   (unsigned long)seq->private, handler->name);	if (handler->fops)		seq_printf(seq, " Minor=%d", handler->minor);	seq_putc(seq, '\n');	return 0;}static struct seq_operations input_handlers_seq_ops = {	.start	= input_handlers_seq_start,	.next	= input_handlers_seq_next,	.stop	= input_handlers_seq_stop,	.show	= input_handlers_seq_show,};static int input_proc_handlers_open(struct inode *inode, struct file *file){	return seq_open(file, &input_handlers_seq_ops);}static const struct file_operations input_handlers_fileops = {	.owner		= THIS_MODULE,	.open		= input_proc_handlers_open,	.read		= seq_read,	.llseek		= seq_lseek,	.release	= seq_release,};static int __init input_proc_init(void){	struct proc_dir_entry *entry;	proc_bus_input_dir = proc_mkdir("input", proc_bus);	if (!proc_bus_input_dir)		return -ENOMEM;	proc_bus_input_dir->owner = THIS_MODULE;	entry = create_proc_entry("devices", 0, proc_bus_input_dir);	if (!entry)		goto fail1;	entry->owner = THIS_MODULE;	entry->proc_fops = &input_devices_fileops;	entry = create_proc_entry("handlers", 0, proc_bus_input_dir);	if (!entry)		goto fail2;	entry->owner = THIS_MODULE;	entry->proc_fops = &input_handlers_fileops;	return 0; fail2:	remove_proc_entry("devices", proc_bus_input_dir); fail1: remove_proc_entry("input", proc_bus);	return -ENOMEM;}static void input_proc_exit(void){	remove_proc_entry("devices", proc_bus_input_dir);	remove_proc_entry("handlers", proc_bus_input_dir);	remove_proc_entry("input", proc_bus);}#else /* !CONFIG_PROC_FS */static inline void input_wakeup_procfs_readers(void) { }static inline int input_proc_init(void) { return 0; }static inline void input_proc_exit(void) { }#endif#define INPUT_DEV_STRING_ATTR_SHOW(name)				\static ssize_t input_dev_show_##name(struct device *dev,		\				     struct device_attribute *attr,	\				     char *buf)				\{									\	struct input_dev *input_dev = to_input_dev(dev);		\									\	return scnprintf(buf, PAGE_SIZE, "%s\n",			\			 input_dev->name ? input_dev->name : "");	\}									\static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL)INPUT_DEV_STRING_ATTR_SHOW(name);INPUT_DEV_STRING_ATTR_SHOW(phys);INPUT_DEV_STRING_ATTR_SHOW(uniq);static int input_print_modalias_bits(char *buf, int size,				     char name, unsigned long *bm,				     unsigned int min_bit, unsigned int max_bit){	int len = 0, i;	len += snprintf(buf, max(size, 0), "%c", name);	for (i = min_bit; i < max_bit; i++)		if (bm[BIT_WORD(i)] & BIT_MASK(i))			len += snprintf(buf + len, max(size - len, 0), "%X,", i);	return len;}static int input_print_modalias(char *buf, int size, struct input_dev *id,				int add_cr){	int len;	len = snprintf(buf, max(size, 0),		       "input:b%04Xv%04Xp%04Xe%04X-",		       id->id.bustype, id->id.vendor,		       id->id.product, id->id.version);	len += input_print_modalias_bits(buf + len, size - len,				'e', id->evbit, 0, EV_MAX);	len += input_print_modalias_bits(buf + len, size - len,				'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX);	len += input_print_modalias_bits(buf + len, size - len,				'r', id->relbit, 0, REL_MAX);	len += input_print_modalias_bits(buf + len, size - len,				'a', id->absbit, 0, ABS_MAX);	len += input_print_modalias_bits(buf + len, size - len,				'm', id->mscbit, 0, MSC_MAX);	len += input_print_modalias_bits(buf + len, size - len,				'l', id->ledbit, 0, LED_MAX);	len += input_print_modalias_bits(buf + len, size - len,				's', id->sndbit, 0, SND_MAX);	len += input_print_modalias_bits(buf + len, size - len,				'f', id->ffbit, 0, FF_MAX);	len += input_print_modalias_bits(buf + len, size - len,				'w', id->swbit, 0, SW_MAX);	if (add_cr)		len += snprintf(buf + len, max(size - len, 0), "\n");	return len;}static ssize_t input_dev_show_modalias(struct device *dev,				       struct device_attribute *attr,				       char *buf){	struct input_dev *id = to_input_dev(dev);	ssize_t len;	len = input_print_modalias(buf, PAGE_SIZE, id, 1);	return min_t(int, len, PAGE_SIZE);}static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);static struct attribute *input_dev_attrs[] = {	&dev_attr_name.attr,	&dev_attr_phys.attr,	&dev_attr_uniq.attr,	&dev_attr_modalias.attr,	NULL};static struct attribute_group input_dev_attr_group = {	.attrs	= input_dev_attrs,};#define INPUT_DEV_ID_ATTR(name)						\static ssize_t input_dev_show_id_##name(struct device *dev,		\					struct device_attribute *attr,	\					char *buf)			\{									\	struct input_dev *input_dev = to_input_dev(dev);		\	return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name);	\}									\static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL)INPUT_DEV_ID_ATTR(bustype);INPUT_DEV_ID_ATTR(vendor);INPUT_DEV_ID_ATTR(product);INPUT_DEV_ID_ATTR(version);static struct attribute *input_dev_id_attrs[] = {	&dev_attr_bustype.attr,	&dev_attr_vendor.attr,	&dev_attr_product.attr,	&dev_attr_version.attr,	NULL};static struct attribute_group input_dev_id_attr_group = {	.name	= "id",	.attrs	= input_dev_id_attrs,};static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,			      int max, int add_cr){	int i;	int len = 0;	for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)		if (bitmap[i])			break;	for (; i >= 0; i--)		len += snprintf(buf + len, max(buf_size - len, 0),				"%lx%s", bitmap[i], i > 0 ? " " : "");	if (add_cr)		len += snprintf(buf + len, max(buf_size - len, 0), "\n");	return len;}#define INPUT_DEV_CAP_ATTR(ev, bm)					\static ssize_t input_dev_show_cap_##bm(struct device *dev,		\				       struct device_attribute *attr,	\				       char *buf)			\{									\	struct input_dev *input_dev = to_input_dev(dev);		\	int len = input_print_bitmap(buf, PAGE_SIZE,			\				     input_dev->bm##bit, ev##_MAX, 1);	\	return min_t(int, len, PAGE_SIZE);				\}									\static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL)INPUT_DEV_CAP_ATTR(EV, ev);INPUT_DEV_CAP_ATTR(KEY, key);INPUT_DEV_CAP_ATTR(REL, rel);INPUT_DEV_CAP_ATTR(ABS, abs);INPUT_DEV_CAP_ATTR(MSC, msc);INPUT_DEV_CAP_ATTR(LED, led);INPUT_DEV_CAP_ATTR(SND, snd);INPUT_DEV_CAP_ATTR(FF, ff);INPUT_DEV_CAP_ATTR(SW, sw);static struct attribute *input_dev_caps_attrs[] = {	&dev_attr_ev.attr,	&dev_attr_key.attr,	&dev_attr_rel.attr,	&dev_attr_abs.attr,	&dev_attr_msc.attr,	&dev_attr_led.attr,	&dev_attr_snd.attr,	&dev_attr_ff.attr,	&dev_attr_sw.attr,	NULL};static struct attribute_group input_dev_caps_attr_group = {	.name	= "capabilities",	.attrs	= input_dev_caps_attrs,};static struct attribute_group *input_dev_attr_groups[] = {	&input_dev_attr_group,	&input_dev_id_attr_group,	&input_dev_caps_attr_group,	NULL};static void input_dev_release(struct device *device){	struct input_dev *dev = to_input_dev(device);	input_ff_destroy(dev);	kfree(dev);	module_put(THIS_MODULE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -