From 47e04b8bffdcb98c6b9fc8003105a6a1f5b51848 Mon Sep 17 00:00:00 2001 From: corentin-soriano Date: Mon, 17 Jun 2024 12:00:34 +0200 Subject: [PATCH] GUACAMOLE-287: Add constants for "magic numbers" in function __guac_terminal_send_key. --- src/terminal/terminal.c | 308 +++++++++++++++++++++++++++++++++------- 1 file changed, 259 insertions(+), 49 deletions(-) diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 3e6c7992c..af927c609 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -51,6 +51,141 @@ #include #include +/** + * Keysym for movement keys (and keypad). + */ +#define GUAC_TERMINAL_KEY_UP 0xFF52 +#define GUAC_TERMINAL_KEY_DOWN 0xFF54 +#define GUAC_TERMINAL_KEY_LEFT 0xFF51 +#define GUAC_TERMINAL_KEY_RIGHT 0xFF53 +#define GUAC_TERMINAL_KEY_HOME 0xFF50 +#define GUAC_TERMINAL_KEY_END 0xFF57 +#define GUAC_TERMINAL_KEY_PAGEUP 0xFF55 +#define GUAC_TERMINAL_KEY_PAGEDOWN 0xFF56 + +/** + * Keysym for keypad movement keys. + */ +#define GUAC_TERMINAL_KEY_KP_UP 0xFF97 +#define GUAC_TERMINAL_KEY_KP_DOWN 0xFF99 +#define GUAC_TERMINAL_KEY_KP_LEFT 0xFF96 +#define GUAC_TERMINAL_KEY_KP_RIGHT 0xFF98 +#define GUAC_TERMINAL_KEY_KP_HOME 0xFF95 +#define GUAC_TERMINAL_KEY_KP_END 0xFF9C +#define GUAC_TERMINAL_KEY_KP_PAGEUP 0xFF9A +#define GUAC_TERMINAL_KEY_KP_PAGEDOWN 0xFF9B + +/** + * Keysym for Control/Meta/ALT/Shift (left and right keys). + */ +#define GUAC_TERMINAL_KEY_CTRL_L 0xFFE3 +#define GUAC_TERMINAL_KEY_CTRL_R 0xFFE4 +#define GUAC_TERMINAL_KEY_META_L 0xFFE7 +#define GUAC_TERMINAL_KEY_META_R 0xFFE8 +#define GUAC_TERMINAL_KEY_ALT_L 0xFFE9 +#define GUAC_TERMINAL_KEY_ALT_R 0xFFEA +#define GUAC_TERMINAL_KEY_SHIFT_L 0xFFE1 +#define GUAC_TERMINAL_KEY_SHIFT_R 0xFFE2 + +/** + * Keysym for special keys. + */ +#define GUAC_TERMINAL_KEY_ESCAPE 0xFF1B +#define GUAC_TERMINAL_KEY_INSERT 0xFF63 +#define GUAC_TERMINAL_KEY_ENTER 0xFF0D +#define GUAC_TERMINAL_KEY_TAB 0xFF09 +#define GUAC_TERMINAL_KEY_BACKSPACE 0xFF08 +#define GUAC_TERMINAL_KEY_DELETE 0xFFFF + + +/** + * Keysym for keypad special keys. + */ +#define GUAC_TERMINAL_KEY_KP_INSERT 0xFF9E +#define GUAC_TERMINAL_KEY_KP_ENTER 0xFF8D +#define GUAC_TERMINAL_KEY_KP_TAB 0xFF89 +#define GUAC_TERMINAL_KEY_KP_DELETE 0xFF9F + +/** + * Keysym for Function keys (1-12). + */ +#define GUAC_TERMINAL_KEY_F1 0xFFBE +#define GUAC_TERMINAL_KEY_F2 0xFFBF +#define GUAC_TERMINAL_KEY_F3 0xFFC0 +#define GUAC_TERMINAL_KEY_F4 0xFFC1 +#define GUAC_TERMINAL_KEY_F5 0xFFC2 +#define GUAC_TERMINAL_KEY_F6 0xFFC3 +#define GUAC_TERMINAL_KEY_F7 0xFFC4 +#define GUAC_TERMINAL_KEY_F8 0xFFC5 +#define GUAC_TERMINAL_KEY_F9 0xFFC6 +#define GUAC_TERMINAL_KEY_F10 0xFFC7 +#define GUAC_TERMINAL_KEY_F11 0xFFC8 +#define GUAC_TERMINAL_KEY_F12 0xFFC9 + +/** + * Keysym for keypad Function keys (1-4). + */ +#define GUAC_TERMINAL_KEY_KP_F1 0xFF91 +#define GUAC_TERMINAL_KEY_KP_F2 0xFF92 +#define GUAC_TERMINAL_KEY_KP_F3 0xFF93 +#define GUAC_TERMINAL_KEY_KP_F4 0xFF94 + +/** + * Hex ASCII codes. + */ +#define GUAC_TERMINAL_ASCII_TAB "\x09" +#define GUAC_TERMINAL_ASCII_CR "\x0D" +#define GUAC_TERMINAL_ASCII_ESCAPE "\x1B" + +/** + * Escape sequence: special keys. + */ +#define GUAC_TERMINAL_ESC_SEQ_PAGEUP "\x1B[5~" +#define GUAC_TERMINAL_ESC_SEQ_PAGEDOWN "\x1B[6~" +#define GUAC_TERMINAL_ESC_SEQ_END "\x1B[4~" +#define GUAC_TERMINAL_ESC_SEQ_INSERT "\x1B[2~" +#define GUAC_TERMINAL_ESC_SEQ_HOME "\x1B[1~" +#define GUAC_TERMINAL_ESC_SEQ_CURSOR_LEFT "\x1B[D" +#define GUAC_TERMINAL_ESC_SEQ_CURSOR_RIGHT "\x1B[C" +#define GUAC_TERMINAL_ESC_SEQ_CURSOR_UP "\x1B[A" +#define GUAC_TERMINAL_ESC_SEQ_CURSOR_DOWN "\x1B[B" +#define GUAC_TERMINAL_ESC_SEQ_DELETE "\x1B[3~" + +/** + * Escape sequence: application cursor. + */ +#define GUAC_TERMINAL_ESC_SEQ_APP_CURSOR_LEFT "\x1BOD" +#define GUAC_TERMINAL_ESC_SEQ_APP_CURSOR_RIGHT "\x1BOC" +#define GUAC_TERMINAL_ESC_SEQ_APP_CURSOR_UP "\x1BOA" +#define GUAC_TERMINAL_ESC_SEQ_APP_CURSOR_DOWN "\x1BOB" + +/** + * Escape sequence: function keys. + */ +#define GUAC_TERMINAL_ESC_SEQ_F1 "\x1B[[A" +#define GUAC_TERMINAL_ESC_SEQ_F2 "\x1B[[B" +#define GUAC_TERMINAL_ESC_SEQ_F3 "\x1B[[C" +#define GUAC_TERMINAL_ESC_SEQ_F4 "\x1B[[D" +#define GUAC_TERMINAL_ESC_SEQ_F5 "\x1B[[E" +#define GUAC_TERMINAL_ESC_SEQ_F6 "\x1B[17~" +#define GUAC_TERMINAL_ESC_SEQ_F7 "\x1B[18~" +#define GUAC_TERMINAL_ESC_SEQ_F8 "\x1B[19~" +#define GUAC_TERMINAL_ESC_SEQ_F9 "\x1B[20~" +#define GUAC_TERMINAL_ESC_SEQ_F10 "\x1B[21~" +#define GUAC_TERMINAL_ESC_SEQ_F11 "\x1B[22~" +#define GUAC_TERMINAL_ESC_SEQ_F12 "\x1B[23~" + +/** + * Escape sequence: go to previous/next word. + */ +#define GUAC_TERMINAL_ESC_SEQ_PREV_WORD "\033[1;5D" +#define GUAC_TERMINAL_ESC_SEQ_NEXT_WORD "\033[1;5C" + +/** + * Escape sequence: delete word. + */ +#define GUAC_TERMINAL_ESC_SEQ_DELETE_WORD "\033D" + /** * Sets the given range of columns to the given character. */ @@ -1583,13 +1718,13 @@ static int __guac_terminal_send_key(guac_terminal* term, int keysym, int pressed } /* Track modifiers */ - if (keysym == 0xFFE3 || keysym == 0xFFE4) + if (keysym == GUAC_TERMINAL_KEY_CTRL_L || keysym == GUAC_TERMINAL_KEY_CTRL_R) term->mod_ctrl = pressed; - else if (keysym == 0xFFE7 || keysym == 0xFFE8) + else if (keysym == GUAC_TERMINAL_KEY_META_L || keysym == GUAC_TERMINAL_KEY_META_R) term->mod_meta = pressed; - else if (keysym == 0xFFE9 || keysym == 0xFFEA) + else if (keysym == GUAC_TERMINAL_KEY_ALT_L || keysym == GUAC_TERMINAL_KEY_ALT_R) term->mod_alt = pressed; - else if (keysym == 0xFFE1 || keysym == 0xFFE2) + else if (keysym == GUAC_TERMINAL_KEY_SHIFT_L || keysym == GUAC_TERMINAL_KEY_SHIFT_R) term->mod_shift = pressed; /* If key pressed */ @@ -1612,37 +1747,37 @@ static int __guac_terminal_send_key(guac_terminal* term, int keysym, int pressed if (term->mod_shift) { /* Home */ - if (keysym == 0xFF50 || keysym == 0xFF95) { + if (keysym == GUAC_TERMINAL_KEY_HOME || keysym == GUAC_TERMINAL_KEY_KP_HOME) { guac_terminal_scroll_display_up(term, term->max_scrollback); return 0; } /* End */ - if (keysym == 0xFF57 || keysym == 0xFF9C) { + if (keysym == GUAC_TERMINAL_KEY_END || keysym == GUAC_TERMINAL_KEY_KP_END) { guac_terminal_scroll_display_down(term, term->max_scrollback); return 0; } /* Page up */ - if (keysym == 0xFF55) { + if (keysym == GUAC_TERMINAL_KEY_PAGEUP || keysym == GUAC_TERMINAL_KEY_KP_PAGEUP) { guac_terminal_scroll_display_up(term, term->term_height); return 0; } /* Page down */ - if (keysym == 0xFF56) { + if (keysym == GUAC_TERMINAL_KEY_PAGEDOWN || keysym == GUAC_TERMINAL_KEY_KP_PAGEDOWN) { guac_terminal_scroll_display_down(term, term->term_height); return 0; } /* Up */ - if (keysym == 0xFF52 || keysym == 0xFF97) { + if (keysym == GUAC_TERMINAL_KEY_UP || keysym == GUAC_TERMINAL_KEY_KP_UP) { guac_terminal_scroll_display_up(term, 1); return 0; } /* Down */ - if (keysym == 0xFF54 || keysym == 0xFF99) { + if (keysym == GUAC_TERMINAL_KEY_DOWN || keysym == GUAC_TERMINAL_KEY_KP_DOWN) { guac_terminal_scroll_display_down(term, 1); return 0; } @@ -1655,7 +1790,7 @@ static int __guac_terminal_send_key(guac_terminal* term, int keysym, int pressed /* If alt being held, also send escape character */ if (term->mod_alt) - guac_terminal_send_string(term, "\x1B"); + guac_terminal_send_string(term, GUAC_TERMINAL_ASCII_ESCAPE); /* Translate Ctrl+letter to control code */ if (term->mod_ctrl) { @@ -1683,20 +1818,20 @@ static int __guac_terminal_send_key(guac_terminal* term, int keysym, int pressed data = (char) (keysym - '3' + 0x1B); /* CTRL+Left: return to previous word */ - else if (keysym == 0xFF51 || keysym == 0xFF96) - return guac_terminal_send_string(term, "\033[1;5D"); + else if (keysym == GUAC_TERMINAL_KEY_LEFT || keysym == GUAC_TERMINAL_KEY_KP_LEFT) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_PREV_WORD); /* CTRL+Right: go to next word */ - else if (keysym == 0xFF53 || keysym == 0xFF98) - return guac_terminal_send_string(term, "\033[1;5C"); + else if (keysym == GUAC_TERMINAL_KEY_RIGHT || keysym == GUAC_TERMINAL_KEY_KP_RIGHT) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_NEXT_WORD); /* CTRL+Backspace: remove word (map to CTRL+w) */ - else if (keysym == 0xFF08) + else if (keysym == GUAC_TERMINAL_KEY_BACKSPACE) data = (char) 23; /* CTRL+Supr: remove word to right */ - else if (keysym == 0xFFFF) - return guac_terminal_send_string(term, "\033D"); + else if (keysym == GUAC_TERMINAL_KEY_DELETE || keysym == GUAC_TERMINAL_KEY_KP_DELETE) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_DELETE_WORD); /* Otherwise ignore */ else @@ -1727,51 +1862,126 @@ static int __guac_terminal_send_key(guac_terminal* term, int keysym, int pressed else { /* Backspace can vary based on configuration of terminal by client. */ - if (keysym == 0xFF08) { + if (keysym == GUAC_TERMINAL_KEY_BACKSPACE) { char backspace_str[] = { term->backspace, '\0' }; return guac_terminal_send_string(term, backspace_str); } - if (keysym == 0xFF09 || keysym == 0xFF89) return guac_terminal_send_string(term, "\x09"); /* Tab */ - if (keysym == 0xFF0D || keysym == 0xFF8D) return guac_terminal_send_string(term, "\x0D"); /* Enter */ - if (keysym == 0xFF1B) return guac_terminal_send_string(term, "\x1B"); /* Esc */ - if (keysym == 0xFF50 || keysym == 0xFF95) return guac_terminal_send_string(term, "\x1B[1~"); /* Home */ + /* Tab */ + if (keysym == GUAC_TERMINAL_KEY_TAB || keysym == GUAC_TERMINAL_KEY_KP_TAB) + return guac_terminal_send_string(term, GUAC_TERMINAL_ASCII_TAB); + + /* Enter */ + if (keysym == GUAC_TERMINAL_KEY_ENTER || keysym == GUAC_TERMINAL_KEY_KP_ENTER) + return guac_terminal_send_string(term, GUAC_TERMINAL_ASCII_CR); + + /* Esc */ + if (keysym == GUAC_TERMINAL_KEY_ESCAPE) + return guac_terminal_send_string(term, GUAC_TERMINAL_ASCII_ESCAPE); + + /* Home */ + if (keysym == GUAC_TERMINAL_KEY_HOME || keysym == GUAC_TERMINAL_KEY_KP_HOME) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_HOME); /* Arrow keys w/ application cursor */ if (term->application_cursor_keys) { - if (keysym == 0xFF51 || keysym == 0xFF96) return guac_terminal_send_string(term, "\x1BOD"); /* Left */ - if (keysym == 0xFF52 || keysym == 0xFF97) return guac_terminal_send_string(term, "\x1BOA"); /* Up */ - if (keysym == 0xFF53 || keysym == 0xFF98) return guac_terminal_send_string(term, "\x1BOC"); /* Right */ - if (keysym == 0xFF54 || keysym == 0xFF99) return guac_terminal_send_string(term, "\x1BOB"); /* Down */ + + /* Left */ + if (keysym == GUAC_TERMINAL_KEY_LEFT || keysym == GUAC_TERMINAL_KEY_KP_LEFT) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_APP_CURSOR_LEFT); + + /* Up */ + if (keysym == GUAC_TERMINAL_KEY_UP || keysym == GUAC_TERMINAL_KEY_KP_UP) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_APP_CURSOR_UP); + + /* Right */ + if (keysym == GUAC_TERMINAL_KEY_RIGHT || keysym == GUAC_TERMINAL_KEY_KP_RIGHT) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_APP_CURSOR_RIGHT); + + /* Down */ + if (keysym == GUAC_TERMINAL_KEY_DOWN || keysym == GUAC_TERMINAL_KEY_KP_DOWN) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_APP_CURSOR_DOWN); } else { - if (keysym == 0xFF51 || keysym == 0xFF96) return guac_terminal_send_string(term, "\x1B[D"); /* Left */ - if (keysym == 0xFF52 || keysym == 0xFF97) return guac_terminal_send_string(term, "\x1B[A"); /* Up */ - if (keysym == 0xFF53 || keysym == 0xFF98) return guac_terminal_send_string(term, "\x1B[C"); /* Right */ - if (keysym == 0xFF54 || keysym == 0xFF99) return guac_terminal_send_string(term, "\x1B[B"); /* Down */ - } - if (keysym == 0xFF55 || keysym == 0xFF9A) return guac_terminal_send_string(term, "\x1B[5~"); /* Page up */ - if (keysym == 0xFF56 || keysym == 0xFF9B) return guac_terminal_send_string(term, "\x1B[6~"); /* Page down */ - if (keysym == 0xFF57 || keysym == 0xFF9C) return guac_terminal_send_string(term, "\x1B[4~"); /* End */ + /* Left */ + if (keysym == GUAC_TERMINAL_KEY_LEFT || keysym == GUAC_TERMINAL_KEY_KP_LEFT) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_CURSOR_LEFT); - if (keysym == 0xFF63 || keysym == 0xFF9E) return guac_terminal_send_string(term, "\x1B[2~"); /* Insert */ + /* Up */ + if (keysym == GUAC_TERMINAL_KEY_UP || keysym == GUAC_TERMINAL_KEY_KP_UP) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_CURSOR_UP); - if (keysym == 0xFFBE || keysym == 0xFF91) return guac_terminal_send_string(term, "\x1B[[A"); /* F1 */ - if (keysym == 0xFFBF || keysym == 0xFF92) return guac_terminal_send_string(term, "\x1B[[B"); /* F2 */ - if (keysym == 0xFFC0 || keysym == 0xFF93) return guac_terminal_send_string(term, "\x1B[[C"); /* F3 */ - if (keysym == 0xFFC1 || keysym == 0xFF94) return guac_terminal_send_string(term, "\x1B[[D"); /* F4 */ - if (keysym == 0xFFC2) return guac_terminal_send_string(term, "\x1B[[E"); /* F5 */ + /* Right */ + if (keysym == GUAC_TERMINAL_KEY_RIGHT || keysym == GUAC_TERMINAL_KEY_KP_RIGHT) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_CURSOR_RIGHT); - if (keysym == 0xFFC3) return guac_terminal_send_string(term, "\x1B[17~"); /* F6 */ - if (keysym == 0xFFC4) return guac_terminal_send_string(term, "\x1B[18~"); /* F7 */ - if (keysym == 0xFFC5) return guac_terminal_send_string(term, "\x1B[19~"); /* F8 */ - if (keysym == 0xFFC6) return guac_terminal_send_string(term, "\x1B[20~"); /* F9 */ - if (keysym == 0xFFC7) return guac_terminal_send_string(term, "\x1B[21~"); /* F10 */ - if (keysym == 0xFFC8) return guac_terminal_send_string(term, "\x1B[22~"); /* F11 */ - if (keysym == 0xFFC9) return guac_terminal_send_string(term, "\x1B[23~"); /* F12 */ + /* Down */ + if (keysym == GUAC_TERMINAL_KEY_DOWN || keysym == GUAC_TERMINAL_KEY_KP_DOWN) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_CURSOR_DOWN); + } + + /* Page up */ + if (keysym == GUAC_TERMINAL_KEY_PAGEUP || keysym == GUAC_TERMINAL_KEY_KP_PAGEUP) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_PAGEUP); - if (keysym == 0xFFFF || keysym == 0xFF9F) return guac_terminal_send_string(term, "\x1B[3~"); /* Delete */ + /* Page down */ + if (keysym == GUAC_TERMINAL_KEY_PAGEDOWN || keysym == GUAC_TERMINAL_KEY_KP_PAGEDOWN) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_PAGEDOWN); + + /* End */ + if (keysym == GUAC_TERMINAL_KEY_END || keysym == GUAC_TERMINAL_KEY_KP_END) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_END); + + /* Insert */ + if (keysym == GUAC_TERMINAL_KEY_INSERT || keysym == GUAC_TERMINAL_KEY_KP_INSERT) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_INSERT); + + /* F1 */ + if (keysym == GUAC_TERMINAL_KEY_F1 || keysym == GUAC_TERMINAL_KEY_KP_F1) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F1); + + /* F2 */ + if (keysym == GUAC_TERMINAL_KEY_F2 || keysym == GUAC_TERMINAL_KEY_KP_F2) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F2); + + /* F3 */ + if (keysym == GUAC_TERMINAL_KEY_F3 || keysym == GUAC_TERMINAL_KEY_KP_F3) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F3); + + /* F4 */ + if (keysym == GUAC_TERMINAL_KEY_F4 || keysym == GUAC_TERMINAL_KEY_KP_F4) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F4); + + /* F5 */ + if (keysym == GUAC_TERMINAL_KEY_F5) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F5); + + /* F6 */ + if (keysym == GUAC_TERMINAL_KEY_F6) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F6); + /* F7 */ + if (keysym == GUAC_TERMINAL_KEY_F7) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F7); + /* F8 */ + if (keysym == GUAC_TERMINAL_KEY_F8) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F8); + /* F9 */ + if (keysym == GUAC_TERMINAL_KEY_F9) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F9); + /* F10 */ + if (keysym == GUAC_TERMINAL_KEY_F10) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F10); + /* F11 */ + if (keysym == GUAC_TERMINAL_KEY_F11) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F11); + /* F12 */ + if (keysym == GUAC_TERMINAL_KEY_F12) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_F12); + + /* Delete */ + if (keysym == GUAC_TERMINAL_KEY_DELETE || keysym == GUAC_TERMINAL_KEY_KP_DELETE) + return guac_terminal_send_string(term, GUAC_TERMINAL_ESC_SEQ_DELETE); /* Ignore unknown keys */ guac_client_log(term->client, GUAC_LOG_DEBUG,