Commit 44abe47debc783396ec48d929844dcf1106b72f3

Authored by Hung-Te Lin
Committed by Tom Rini
1 parent 59a1b72ced

input: Add ANSI 3.64 escape sequence generation.

To support Non-ASCII keys (ex, Fn, PgUp/Dn, arrow keys, ...), we need to
translate key code into escape sequence.

(Updated by sjg@chromium.org to move away from a function to store
keycodes, so we can easily record how many were sent. We now need to
return this from input_send_keycodes() so we know whether keys were
generated.)

Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Rini <trini@ti.com>

Showing 2 changed files with 89 additions and 15 deletions Side-by-side Diff

drivers/input/input.c
... ... @@ -93,7 +93,23 @@
93 93 '\r', 0xff, 0xff
94 94 };
95 95  
  96 +/*
  97 + * Scan key code to ANSI 3.64 escape sequence table. This table is
  98 + * incomplete in that it does not include all possible extra keys.
  99 + */
  100 +static struct {
  101 + int kbd_scan_code;
  102 + char *escape;
  103 +} kbd_to_ansi364[] = {
  104 + { KEY_UP, "\033[A"},
  105 + { KEY_DOWN, "\033[B"},
  106 + { KEY_RIGHT, "\033[C"},
  107 + { KEY_LEFT, "\033[D"},
  108 +};
96 109  
  110 +/* Maximum number of output characters that an ANSI sequence expands to */
  111 +#define ANSI_CHAR_MAX 3
  112 +
97 113 int input_queue_ascii(struct input_config *config, int ch)
98 114 {
99 115 if (config->fifo_in + 1 == INPUT_BUFFER_LEN) {
100 116  
101 117  
102 118  
103 119  
104 120  
105 121  
... ... @@ -289,24 +305,67 @@
289 305 }
290 306  
291 307 /**
  308 + * Checks and converts a special key code into ANSI 3.64 escape sequence.
  309 + *
  310 + * @param config Input state
  311 + * @param keycode Key code to examine
  312 + * @param output_ch Buffer to place output characters into. It should
  313 + * be at least ANSI_CHAR_MAX bytes long, to allow for
  314 + * an ANSI sequence.
  315 + * @param max_chars Maximum number of characters to add to output_ch
  316 + * @return number of characters output, if the key was converted, otherwise 0.
  317 + * This may be larger than max_chars, in which case the overflow
  318 + * characters are not output.
  319 + */
  320 +static int input_keycode_to_ansi364(struct input_config *config,
  321 + int keycode, char output_ch[], int max_chars)
  322 +{
  323 + const char *escape;
  324 + int ch_count;
  325 + int i;
  326 +
  327 + for (i = ch_count = 0; i < ARRAY_SIZE(kbd_to_ansi364); i++) {
  328 + if (keycode != kbd_to_ansi364[i].kbd_scan_code)
  329 + continue;
  330 + for (escape = kbd_to_ansi364[i].escape; *escape; escape++) {
  331 + if (ch_count < max_chars)
  332 + output_ch[ch_count] = *escape;
  333 + ch_count++;
  334 + }
  335 + return ch_count;
  336 + }
  337 +
  338 + return 0;
  339 +}
  340 +
  341 +/**
  342 + * Converts and queues a list of key codes in escaped ASCII string form
292 343 * Convert a list of key codes into ASCII
293 344 *
294 345 * You must call input_check_keycodes() before this. It turns the keycode
295   - * list into a list of ASCII characters which are ready to send to the
296   - * input layer.
  346 + * list into a list of ASCII characters and sends them to the input layer.
297 347 *
298 348 * Characters which were seen last time do not generate fresh ASCII output.
  349 + * The output (calls to queue_ascii) may be longer than num_keycodes, if the
  350 + * keycode contains special keys that was encoded to longer escaped sequence.
299 351 *
300 352 * @param config Input state
301 353 * @param keycode List of key codes to examine
302 354 * @param num_keycodes Number of key codes
  355 + * @param output_ch Buffer to place output characters into. It should
  356 + * be at last ANSI_CHAR_MAX * num_keycodes, to allow for
  357 + * ANSI sequences.
  358 + * @param max_chars Maximum number of characters to add to output_ch
303 359 * @param same Number of key codes which are the same
  360 + * @return number of characters written into output_ch, or -1 if we would
  361 + * exceed max_chars chars.
304 362 */
305 363 static int input_keycodes_to_ascii(struct input_config *config,
306   - int keycode[], int num_keycodes, char output_ch[], int same)
  364 + int keycode[], int num_keycodes, char output_ch[],
  365 + int max_chars, int same)
307 366 {
308 367 struct input_key_xlate *table;
309   - int ch_count;
  368 + int ch_count = 0;
310 369 int i;
311 370  
312 371 table = &config->table[0];
313 372  
314 373  
315 374  
... ... @@ -321,19 +380,31 @@
321 380 }
322 381 }
323 382  
324   - /* now find normal keys */
325   - for (i = ch_count = 0; i < num_keycodes; i++) {
  383 + /* Start conversion by looking for the first new keycode (by same). */
  384 + for (i = same; i < num_keycodes; i++) {
326 385 int key = keycode[i];
  386 + int ch = (key < table->num_entries) ? table->xlate[key] : 0xff;
327 387  
328   - if (key < table->num_entries && i >= same) {
329   - int ch = table->xlate[key];
330   -
331   - /* If a normal key with an ASCII value, add it! */
332   - if (ch != 0xff)
333   - output_ch[ch_count++] = (uchar)ch;
  388 + /*
  389 + * For a normal key (with an ASCII value), add it; otherwise
  390 + * translate special key to escape sequence if possible.
  391 + */
  392 + if (ch != 0xff) {
  393 + if (ch_count < max_chars)
  394 + output_ch[ch_count] = (uchar)ch;
  395 + ch_count++;
  396 + } else {
  397 + ch_count += input_keycode_to_ansi364(config, key,
  398 + output_ch, max_chars);
334 399 }
335 400 }
336 401  
  402 + if (ch_count > max_chars) {
  403 + debug("%s: Output char buffer overflow size=%d, need=%d\n",
  404 + __func__, max_chars, ch_count);
  405 + return -1;
  406 + }
  407 +
337 408 /* ok, so return keys */
338 409 return ch_count;
339 410 }
... ... @@ -341,7 +412,7 @@
341 412 int input_send_keycodes(struct input_config *config,
342 413 int keycode[], int num_keycodes)
343 414 {
344   - char ch[num_keycodes];
  415 + char ch[num_keycodes * ANSI_CHAR_MAX];
345 416 int count, i, same = 0;
346 417 int is_repeat = 0;
347 418 unsigned delay_ms;
... ... @@ -363,7 +434,7 @@
363 434 }
364 435  
365 436 count = input_keycodes_to_ascii(config, keycode, num_keycodes,
366   - ch, is_repeat ? 0 : same);
  437 + ch, sizeof(ch), is_repeat ? 0 : same);
367 438 for (i = 0; i < count; i++)
368 439 input_queue_ascii(config, ch[i]);
369 440 delay_ms = is_repeat ?
... ... @@ -371,7 +442,8 @@
371 442 config->repeat_delay_ms;
372 443  
373 444 config->next_repeat_ms = get_timer(0) + delay_ms;
374   - return 0;
  445 +
  446 + return count;
375 447 }
376 448  
377 449 int input_add_table(struct input_config *config, int left_keycode,
... ... @@ -84,6 +84,8 @@
84 84 * @param config Input state
85 85 * @param keycode List of key codes to examine
86 86 * @param num_keycodes Number of key codes
  87 + * @return number of ascii characters sent, or 0 if none, or -1 for an
  88 + * internal error
87 89 */
88 90 int input_send_keycodes(struct input_config *config, int keycode[], int count);
89 91