Merge branch 'main' into 'main'

Add support for CSI sequences

Closes #166

See merge request plymouth/plymouth!162
This commit is contained in:
Ray Strode 2022-02-22 15:41:50 +00:00
commit d7bd39aaa5
3 changed files with 71 additions and 2 deletions

View file

@ -48,6 +48,12 @@
#define KEY_RETURN '\n'
#define KEY_BACKSPACE '\177'
#define CSI_SEQUENCE_PREFIX "\033["
#define CSI_SEQUENCE_MINIMUM_LENGTH (strlen (CSI_SEQUENCE_PREFIX) + 1)
#define FUNCTION_KEY_SEQUENCE_PREFIX (CSI_SEQUENCE_PREFIX "[")
#define FUNCTION_KEY_SEQUENCE_MINIMUM_LENGTH (strlen (FUNCTION_KEY_SEQUENCE_PREFIX) + 1)
typedef void (*ply_keyboard_handler_t) (void *);
typedef struct
@ -195,7 +201,11 @@ process_keyboard_input (ply_keyboard_t *keyboard,
wchar_t key;
ply_list_node_t *node;
if ((ssize_t) mbrtowc (&key, keyboard_input, character_size, NULL) > 0) {
if (keyboard_input[0] == KEY_ESCAPE && character_size >= 2){
/* Escape sequence */
ply_buffer_append_bytes (keyboard->line_buffer,
keyboard_input, character_size);
} else if ((ssize_t) mbrtowc (&key, keyboard_input, character_size, NULL) > 0) {
switch (key) {
case KEY_CTRL_U:
case KEY_CTRL_W:
@ -270,8 +280,46 @@ on_key_event (ply_keyboard_t *keyboard,
while (i < size) {
ssize_t character_size;
char *keyboard_input;
size_t bytes_left = size - i;
character_size = (ssize_t) ply_utf8_character_get_size (bytes + i, size - i);
/* Control Sequence Introducer sequences
*/
if(bytes_left >= FUNCTION_KEY_SEQUENCE_MINIMUM_LENGTH &&
strncmp (bytes + i, FUNCTION_KEY_SEQUENCE_PREFIX,
strlen (FUNCTION_KEY_SEQUENCE_PREFIX)) == 0) {
/* Special case - CSI [ after which the next character
* is a function key
*/
process_keyboard_input (keyboard, bytes + i, 4);
i += 4;
continue;
} else if(bytes_left >= CSI_SEQUENCE_MINIMUM_LENGTH && /* At least CSI + final byte */
strncmp (bytes + i, CSI_SEQUENCE_PREFIX,
strlen (CSI_SEQUENCE_PREFIX)) == 0) {
ssize_t csi_seq_size;
csi_seq_size = 0;
for (size_t j = strlen (CSI_SEQUENCE_PREFIX); j < bytes_left; j++) {
if ((bytes[i + j] >= 0x40) &&
(bytes[i + j] <= 0x7E)) {
/* Final byte found */
csi_seq_size = j + 1;
break;
}
/* We presume if we aren't at the final byte, the intermediate
* bytes will be in the range 0x20-0x2F, but we don't validate
* that, since it's not really clear how invalid sequences should
* be handled, and letting them through to the keyboard input
* handlers seems just as reasonable as alternatives.
*/
}
if (csi_seq_size == 0) /* No final byte found */
continue;
process_keyboard_input (keyboard, bytes + i, csi_seq_size);
i += csi_seq_size;
continue;
}
character_size = (ssize_t) ply_utf8_character_get_size (bytes + i, bytes_left);
if (character_size < 0)
break;

View file

@ -1516,6 +1516,8 @@ on_keyboard_input (state_t *state,
ply_buffer_clear (state->entry_buffer);
ply_list_remove_node (state->entry_triggers, node);
free (entry_trigger);
} else if (character_size >= 2 && keyboard_input[0] == '\033') {
/* Ignore escape sequences */
} else {
ply_buffer_append_bytes (state->entry_buffer, keyboard_input, character_size);
}

View file

@ -61,6 +61,21 @@
#include "ply-renderer.h"
#include "ply-renderer-plugin.h"
static const char *function_key_escape_sequence[] = {
"\033[[A", /* F1 */
"\033[[B", /* F2 */
"\033[[C", /* F3 */
"\033[[D", /* F4 */
"\033[[E", /* F5 */
"\033[17~", /* F6 */
"\033[18~", /* F7 */
"\033[19~", /* F8 */
"\033[20~", /* F9 */
"\033[21~", /* F10 */
"\033[22~", /* F11 */
"\033[23~", /* F12 */
};
struct _ply_renderer_head
{
ply_renderer_backend_t *backend;
@ -482,6 +497,10 @@ on_key_event (GtkWidget *widget,
ply_buffer_append_bytes (input_source->key_buffer, "\033", 1);
} else if (event->keyval == GDK_KEY_BackSpace) { /* Backspace */
ply_buffer_append_bytes (input_source->key_buffer, "\177", 1);
} else if (GDK_KEY_F1 <= event->keyval &&
GDK_KEY_F12 >= event->keyval) { /* F1-F12 */
const char *key = function_key_escape_sequence[event->keyval - GDK_KEY_F1];
ply_buffer_append_bytes (input_source->key_buffer, key, strlen(key));
} else {
gchar bytes[7];
int byte_count;