diff options
-rw-r--r-- | drivers/input/input.c | 41 | ||||
-rw-r--r-- | include/linux/input.h | 8 |
2 files changed, 42 insertions, 7 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 6c161e220868..7080a9d4b840 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -86,12 +86,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) | |||
86 | } | 86 | } |
87 | 87 | ||
88 | /* | 88 | /* |
89 | * Pass event through all open handles. This function is called with | 89 | * Pass event first through all filters and then, if event has not been |
90 | * filtered out, through all open handles. This function is called with | ||
90 | * dev->event_lock held and interrupts disabled. | 91 | * dev->event_lock held and interrupts disabled. |
91 | */ | 92 | */ |
92 | static void input_pass_event(struct input_dev *dev, | 93 | static void input_pass_event(struct input_dev *dev, |
93 | unsigned int type, unsigned int code, int value) | 94 | unsigned int type, unsigned int code, int value) |
94 | { | 95 | { |
96 | struct input_handler *handler; | ||
95 | struct input_handle *handle; | 97 | struct input_handle *handle; |
96 | 98 | ||
97 | rcu_read_lock(); | 99 | rcu_read_lock(); |
@@ -99,11 +101,25 @@ static void input_pass_event(struct input_dev *dev, | |||
99 | handle = rcu_dereference(dev->grab); | 101 | handle = rcu_dereference(dev->grab); |
100 | if (handle) | 102 | if (handle) |
101 | handle->handler->event(handle, type, code, value); | 103 | handle->handler->event(handle, type, code, value); |
102 | else | 104 | else { |
103 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) | 105 | bool filtered = false; |
104 | if (handle->open) | 106 | |
105 | handle->handler->event(handle, | 107 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) { |
106 | type, code, value); | 108 | if (!handle->open) |
109 | continue; | ||
110 | |||
111 | handler = handle->handler; | ||
112 | if (!handler->filter) { | ||
113 | if (filtered) | ||
114 | break; | ||
115 | |||
116 | handler->event(handle, type, code, value); | ||
117 | |||
118 | } else if (handler->filter(handle, type, code, value)) | ||
119 | filtered = true; | ||
120 | } | ||
121 | } | ||
122 | |||
107 | rcu_read_unlock(); | 123 | rcu_read_unlock(); |
108 | } | 124 | } |
109 | 125 | ||
@@ -990,6 +1006,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v) | |||
990 | union input_seq_state *state = (union input_seq_state *)&seq->private; | 1006 | union input_seq_state *state = (union input_seq_state *)&seq->private; |
991 | 1007 | ||
992 | seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); | 1008 | seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); |
1009 | if (handler->filter) | ||
1010 | seq_puts(seq, " (filter)"); | ||
993 | if (handler->fops) | 1011 | if (handler->fops) |
994 | seq_printf(seq, " Minor=%d", handler->minor); | 1012 | seq_printf(seq, " Minor=%d", handler->minor); |
995 | seq_putc(seq, '\n'); | 1013 | seq_putc(seq, '\n'); |
@@ -1803,7 +1821,16 @@ int input_register_handle(struct input_handle *handle) | |||
1803 | error = mutex_lock_interruptible(&dev->mutex); | 1821 | error = mutex_lock_interruptible(&dev->mutex); |
1804 | if (error) | 1822 | if (error) |
1805 | return error; | 1823 | return error; |
1806 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | 1824 | |
1825 | /* | ||
1826 | * Filters go to the head of the list, normal handlers | ||
1827 | * to the tail. | ||
1828 | */ | ||
1829 | if (handler->filter) | ||
1830 | list_add_rcu(&handle->d_node, &dev->h_list); | ||
1831 | else | ||
1832 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | ||
1833 | |||
1807 | mutex_unlock(&dev->mutex); | 1834 | mutex_unlock(&dev->mutex); |
1808 | 1835 | ||
1809 | /* | 1836 | /* |
diff --git a/include/linux/input.h b/include/linux/input.h index 7be8a6537b57..6c9d3d49fa91 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -1198,6 +1198,8 @@ struct input_handle; | |||
1198 | * @event: event handler. This method is being called by input core with | 1198 | * @event: event handler. This method is being called by input core with |
1199 | * interrupts disabled and dev->event_lock spinlock held and so | 1199 | * interrupts disabled and dev->event_lock spinlock held and so |
1200 | * it may not sleep | 1200 | * it may not sleep |
1201 | * @filter: similar to @event; separates normal event handlers from | ||
1202 | * "filters". | ||
1201 | * @connect: called when attaching a handler to an input device | 1203 | * @connect: called when attaching a handler to an input device |
1202 | * @disconnect: disconnects a handler from input device | 1204 | * @disconnect: disconnects a handler from input device |
1203 | * @start: starts handler for given handle. This function is called by | 1205 | * @start: starts handler for given handle. This function is called by |
@@ -1219,6 +1221,11 @@ struct input_handle; | |||
1219 | * same time. All of them will get their copy of input event generated by | 1221 | * same time. All of them will get their copy of input event generated by |
1220 | * the device. | 1222 | * the device. |
1221 | * | 1223 | * |
1224 | * The very same structure is used to implement input filters. Input core | ||
1225 | * allows filters to run first and will not pass event to regular handlers | ||
1226 | * if any of the filters indicate that the event should be filtered (by | ||
1227 | * returning %true from their filter() method). | ||
1228 | * | ||
1222 | * Note that input core serializes calls to connect() and disconnect() | 1229 | * Note that input core serializes calls to connect() and disconnect() |
1223 | * methods. | 1230 | * methods. |
1224 | */ | 1231 | */ |
@@ -1227,6 +1234,7 @@ struct input_handler { | |||
1227 | void *private; | 1234 | void *private; |
1228 | 1235 | ||
1229 | void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); | 1236 | void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); |
1237 | bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); | ||
1230 | int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); | 1238 | int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); |
1231 | void (*disconnect)(struct input_handle *handle); | 1239 | void (*disconnect)(struct input_handle *handle); |
1232 | void (*start)(struct input_handle *handle); | 1240 | void (*start)(struct input_handle *handle); |