📄 input.c
字号:
}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 + -