diff options
author | Marvin Raaijmakers <marvin_raaijmakers@linux-box.nl> | 2007-03-14 22:50:42 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-03-14 22:50:42 -0400 |
commit | c8e4c77277ca5db0c4ddbfb4bc628b8abad585b0 (patch) | |
tree | 07bebb34767c8c3bd0902d6c2be3f4819b30a7bf /drivers/char/keyboard.c | |
parent | 55e3d9224b60df0fd2dc36bff9b538ce40fd9586 (diff) |
Input: add getkeycode and setkeycode methods
Allow drivers to implement their own get and set keycode methods. This
will allow drivers to change their keymaps without allocating huge
tables covering entire range of possible scancodes.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/char/keyboard.c')
-rw-r--r-- | drivers/char/keyboard.c | 71 |
1 files changed, 23 insertions, 48 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index cb8d691576da..3d211e8553f7 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -159,65 +159,41 @@ static int sysrq_alt_use; | |||
159 | static int sysrq_alt; | 159 | static int sysrq_alt; |
160 | 160 | ||
161 | /* | 161 | /* |
162 | * Translation of scancodes to keycodes. We set them on only the first attached | 162 | * Translation of scancodes to keycodes. We set them on only the first |
163 | * keyboard - for per-keyboard setting, /dev/input/event is more useful. | 163 | * keyboard in the list that accepts the scancode and keycode. |
164 | * Explanation for not choosing the first attached keyboard anymore: | ||
165 | * USB keyboards for example have two event devices: one for all "normal" | ||
166 | * keys and one for extra function keys (like "volume up", "make coffee", | ||
167 | * etc.). So this means that scancodes for the extra function keys won't | ||
168 | * be valid for the first event device, but will be for the second. | ||
164 | */ | 169 | */ |
165 | int getkeycode(unsigned int scancode) | 170 | int getkeycode(unsigned int scancode) |
166 | { | 171 | { |
167 | struct list_head *node; | 172 | struct input_handle *handle; |
168 | struct input_dev *dev = NULL; | 173 | int keycode; |
174 | int error = -ENODEV; | ||
169 | 175 | ||
170 | list_for_each(node, &kbd_handler.h_list) { | 176 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
171 | struct input_handle *handle = to_handle_h(node); | 177 | error = handle->dev->getkeycode(handle->dev, scancode, &keycode); |
172 | if (handle->dev->keycodesize) { | 178 | if (!error) |
173 | dev = handle->dev; | 179 | return keycode; |
174 | break; | ||
175 | } | ||
176 | } | 180 | } |
177 | 181 | ||
178 | if (!dev) | 182 | return error; |
179 | return -ENODEV; | ||
180 | |||
181 | if (scancode >= dev->keycodemax) | ||
182 | return -EINVAL; | ||
183 | |||
184 | return INPUT_KEYCODE(dev, scancode); | ||
185 | } | 183 | } |
186 | 184 | ||
187 | int setkeycode(unsigned int scancode, unsigned int keycode) | 185 | int setkeycode(unsigned int scancode, unsigned int keycode) |
188 | { | 186 | { |
189 | struct list_head *node; | 187 | struct input_handle *handle; |
190 | struct input_dev *dev = NULL; | 188 | int error = -ENODEV; |
191 | unsigned int i, oldkey; | ||
192 | 189 | ||
193 | list_for_each(node, &kbd_handler.h_list) { | 190 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
194 | struct input_handle *handle = to_handle_h(node); | 191 | error = handle->dev->setkeycode(handle->dev, scancode, keycode); |
195 | if (handle->dev->keycodesize) { | 192 | if (!error) |
196 | dev = handle->dev; | ||
197 | break; | 193 | break; |
198 | } | ||
199 | } | 194 | } |
200 | 195 | ||
201 | if (!dev) | 196 | return error; |
202 | return -ENODEV; | ||
203 | |||
204 | if (scancode >= dev->keycodemax) | ||
205 | return -EINVAL; | ||
206 | if (keycode < 0 || keycode > KEY_MAX) | ||
207 | return -EINVAL; | ||
208 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) | ||
209 | return -EINVAL; | ||
210 | |||
211 | oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); | ||
212 | |||
213 | clear_bit(oldkey, dev->keybit); | ||
214 | set_bit(keycode, dev->keybit); | ||
215 | |||
216 | for (i = 0; i < dev->keycodemax; i++) | ||
217 | if (INPUT_KEYCODE(dev,i) == oldkey) | ||
218 | set_bit(oldkey, dev->keybit); | ||
219 | |||
220 | return 0; | ||
221 | } | 197 | } |
222 | 198 | ||
223 | /* | 199 | /* |
@@ -225,10 +201,9 @@ int setkeycode(unsigned int scancode, unsigned int keycode) | |||
225 | */ | 201 | */ |
226 | static void kd_nosound(unsigned long ignored) | 202 | static void kd_nosound(unsigned long ignored) |
227 | { | 203 | { |
228 | struct list_head *node; | 204 | struct input_handle *handle; |
229 | 205 | ||
230 | list_for_each(node, &kbd_handler.h_list) { | 206 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
231 | struct input_handle *handle = to_handle_h(node); | ||
232 | if (test_bit(EV_SND, handle->dev->evbit)) { | 207 | if (test_bit(EV_SND, handle->dev->evbit)) { |
233 | if (test_bit(SND_TONE, handle->dev->sndbit)) | 208 | if (test_bit(SND_TONE, handle->dev->sndbit)) |
234 | input_inject_event(handle, EV_SND, SND_TONE, 0); | 209 | input_inject_event(handle, EV_SND, SND_TONE, 0); |