diff --git a/drivers/input/input.c b/drivers/input/input.c index e65942ec58..530bf5148b 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -107,6 +107,7 @@ static int input_queue_ascii(struct input_config *config, int ch) return -1; /* buffer full */ config->fifo_in++; } + debug(" {%02x} ", ch); config->fifo[config->fifo_in] = (uchar)ch; return 0; @@ -394,8 +395,8 @@ static int input_keycodes_to_ascii(struct input_config *config, return ch_count; } -int input_send_keycodes(struct input_config *config, - int keycode[], int num_keycodes) +static int _input_send_keycodes(struct input_config *config, int keycode[], + int num_keycodes, bool do_send) { char ch[num_keycodes * ANSI_CHAR_MAX]; int count, i, same = 0; @@ -420,8 +421,10 @@ int input_send_keycodes(struct input_config *config, count = input_keycodes_to_ascii(config, keycode, num_keycodes, ch, sizeof(ch), is_repeat ? 0 : same); - for (i = 0; i < count; i++) - input_queue_ascii(config, ch[i]); + if (do_send) { + for (i = 0; i < count; i++) + input_queue_ascii(config, ch[i]); + } delay_ms = is_repeat ? config->repeat_rate_ms : config->repeat_delay_ms; @@ -431,6 +434,41 @@ int input_send_keycodes(struct input_config *config, return count; } +int input_send_keycodes(struct input_config *config, int keycode[], + int num_keycodes) +{ + return _input_send_keycodes(config, keycode, num_keycodes, true); +} + +int input_add_keycode(struct input_config *config, int new_keycode, + bool release) +{ + int keycode[INPUT_MAX_MODIFIERS + 1]; + int count, i; + + /* Add the old keycodes which are not removed by this new one */ + for (i = 0, count = 0; i < config->num_prev_keycodes; i++) { + int code = config->prev_keycodes[i]; + + if (new_keycode == code) { + if (release) + continue; + new_keycode = -1; + } + keycode[count++] = code; + } + + if (!release && new_keycode != -1) + keycode[count++] = new_keycode; + debug("\ncodes for %02x/%d: ", new_keycode, release); + for (i = 0; i < count; i++) + debug("%02x ", keycode[i]); + debug("\n"); + + /* Don't output any ASCII characters if this is a key release */ + return _input_send_keycodes(config, keycode, count, !release); +} + int input_add_table(struct input_config *config, int left_keycode, int right_keycode, const uchar *xlate, int num_entries) { diff --git a/include/input.h b/include/input.h index 71f3538db5..9942d6f77d 100644 --- a/include/input.h +++ b/include/input.h @@ -75,6 +75,26 @@ struct stdio_dev; */ int input_send_keycodes(struct input_config *config, int keycode[], int count); +/** + * Add a new keycode to an existing list of keycodes + * + * This can be used to handle keyboards which do their own scanning. An + * internal list of depressed keys is maintained by the input library. Then + * this function is called to add a new key to the list (when a 'make code' is + * received), or remove a key (when a 'break code' is received). + * + * This function looks after maintenance of the list of active keys, and calls + * input_send_keycodes() with its updated list. + * + * @param config Input state + * @param new_keycode New keycode to add/remove + * @param release true if this key was released, false if depressed + * @return number of ascii characters sent, or 0 if none, or -1 for an + * internal error + */ +int input_add_keycode(struct input_config *config, int new_keycode, + bool release); + /** * Add a new key translation table to the input *