143 lines
6.4 KiB
Diff
143 lines
6.4 KiB
Diff
|
From b41e40e065c60e76b9721747492875c3454440dc Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Mateusz=20Pi=C3=B3rkowski?= <mati7337@protonmail.ch>
|
||
|
Date: Tue, 22 Feb 2022 15:41:49 +0000
|
||
|
Subject: [PATCH] Add support for CSI sequences
|
||
|
|
||
|
---
|
||
|
src/libply-splash-core/ply-keyboard.c | 52 +++++++++++++++++++++++++--
|
||
|
src/main.c | 2 ++
|
||
|
src/plugins/renderers/x11/plugin.c | 19 ++++++++++
|
||
|
3 files changed, 71 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/src/libply-splash-core/ply-keyboard.c b/src/libply-splash-core/ply-keyboard.c
|
||
|
index b174261..b40e961 100644
|
||
|
--- a/src/libply-splash-core/ply-keyboard.c
|
||
|
+++ b/src/libply-splash-core/ply-keyboard.c
|
||
|
@@ -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;
|
||
|
+
|
||
|
+ /* 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, size - i);
|
||
|
+ character_size = (ssize_t) ply_utf8_character_get_size (bytes + i, bytes_left);
|
||
|
|
||
|
if (character_size < 0)
|
||
|
break;
|
||
|
diff --git a/src/main.c b/src/main.c
|
||
|
index 1cb8f6c..bedab7d 100644
|
||
|
--- a/src/main.c
|
||
|
+++ b/src/main.c
|
||
|
@@ -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);
|
||
|
}
|
||
|
diff --git a/src/plugins/renderers/x11/plugin.c b/src/plugins/renderers/x11/plugin.c
|
||
|
index bfb039a..e7169f3 100644
|
||
|
--- a/src/plugins/renderers/x11/plugin.c
|
||
|
+++ b/src/plugins/renderers/x11/plugin.c
|
||
|
@@ -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;
|
||
|
--
|
||
|
2.35.1
|
||
|
|