Author: mesyeti <mesyeti@mesyeti.uk>
add input stuff
source/buffer.c | 5 + source/buffer.h | 1 source/input/sdl.c | 16 +++ source/interpreter/vt100.c | 146 +++++++++++++++++++++++++---- source/keyboard.c | 200 ++++++++++++++++++++------------------- source/keyboard.h | 9 +
diff --git a/source/buffer.c b/source/buffer.c index c4c5ef8954d3fc8441343baec686a1123c153324..49ceab5694012aff86601647afa5b2fb8798069a 100644 --- a/source/buffer.c +++ b/source/buffer.c @@ -154,3 +154,8 @@ buf->buf = new; buf->width = w; buf->height = h; } + +void Buffer_Scroll(Buffer* buf, int by) { + (void) buf; + (void) by; +} diff --git a/source/buffer.h b/source/buffer.h index 488409e0813b2d56df4b25866fd5d55c6a373407..bba44f9bef42764a797cacf0235d34ff095c1520 100644 --- a/source/buffer.h +++ b/source/buffer.h @@ -52,5 +52,6 @@ void Buffer_Print(Buffer* buf, int x, int y, BufAttr attr, const char* str); void Buffer_Blit(Buffer* dest, Buffer* src, int x, int y, Rect clip); void Buffer_HLine(Buffer* buf, int x, int y, int len, BufCell cell); void Buffer_Resize(Buffer* buf, int w, int h); +void Buffer_Scroll(Buffer* buf, int by); #endif diff --git a/source/input/sdl.c b/source/input/sdl.c index a0ae7c9b3362f938832a7558184f2dba8860e3b4..258c0ebf563f78cecf2b78236fea3d5437ea17ce 100644 --- a/source/input/sdl.c +++ b/source/input/sdl.c @@ -102,6 +102,14 @@ case SDL_SCANCODE_KP_7: return KEY_NP_7; case SDL_SCANCODE_KP_8: return KEY_NP_8; case SDL_SCANCODE_KP_9: return KEY_NP_9; case SDL_SCANCODE_KP_PERIOD: return KEY_NP_PERIOD; + case SDL_SCANCODE_LCTRL: return KEY_LCTRL; + case SDL_SCANCODE_LSHIFT: return KEY_LSHIFT; + case SDL_SCANCODE_LALT: return KEY_LALT; + case SDL_SCANCODE_LGUI: return KEY_LMETA; + case SDL_SCANCODE_RCTRL: return KEY_RCTRL; + case SDL_SCANCODE_RSHIFT: return KEY_RSHIFT; + case SDL_SCANCODE_RALT: return KEY_RALT; + case SDL_SCANCODE_RGUI: return KEY_RMETA; default: return 0; } } @@ -203,6 +211,14 @@ case KEY_NP_7: return SDL_SCANCODE_KP_7; case KEY_NP_8: return SDL_SCANCODE_KP_8; case KEY_NP_9: return SDL_SCANCODE_KP_9; case KEY_NP_PERIOD: return SDL_SCANCODE_KP_PERIOD; + case KEY_LCTRL: return SDL_SCANCODE_LCTRL; + case KEY_LSHIFT: return SDL_SCANCODE_LSHIFT; + case KEY_LALT: return SDL_SCANCODE_LALT; + case KEY_LMETA: return SDL_SCANCODE_LGUI; + case KEY_RCTRL: return SDL_SCANCODE_RCTRL; + case KEY_RSHIFT: return SDL_SCANCODE_RSHIFT; + case KEY_RALT: return SDL_SCANCODE_RALT; + case KEY_RMETA: return SDL_SCANCODE_RGUI; default: return 0; } } diff --git a/source/interpreter/vt100.c b/source/interpreter/vt100.c index 8816d3b2a1c97e518c29e04e2984d10fc03ea97a..61239350887a97d7217df088668c64a90b6a38a9 100644 --- a/source/interpreter/vt100.c +++ b/source/interpreter/vt100.c @@ -3,6 +3,8 @@ #include "vt100.h" #include "../mem.h" #include "../util.h" +#include "../input.h" +#include "../keyboard.h" enum { MODE_READY = 0, @@ -27,29 +29,126 @@ bool bracketedPaste; int mouseMode; } Vt100; +static char* KeyToSequence(Key key) { + if ( + (key == KEY_LSHIFT) || (key == KEY_RSHIFT) || (key == KEY_LALT) || + (key == KEY_LCTRL) || (key == KEY_RCTRL) || + (key == KEY_LMETA) || (key == KEY_RMETA) + ) { + return ""; + } + + switch (key) { + case KEY_RETURN: return "\r"; + case KEY_ESCAPE: return Input_KeyPressed(KEY_LALT)? "\x1b\x1b" : "\x1b"; + case KEY_BACKSPACE: return "\x08"; + case KEY_TAB: return "\t"; + default: break; + } + + if (Input_KeyPressed(KEY_LCTRL) || (Input_KeyPressed(KEY_RCTRL))) { + if ((key >= KEY_A) || (key <= KEY_Z)) { + char ch = ((char) (key + ('A' - 1))) & 0x1F; + + static char ret[2]; + ret[0] = ch; + ret[1] = 1; + return ret; + } + } + + int mod = 1; + + if (Input_KeyPressed(KEY_LSHIFT) || (Input_KeyPressed(KEY_RSHIFT))) { + mod += 1; + } + if (Input_KeyPressed(KEY_LALT)) { + mod += 2; + } + if (Input_KeyPressed(KEY_LCTRL) || (Input_KeyPressed(KEY_RCTRL))) { + mod += 4; + } + if (Input_KeyPressed(KEY_LMETA) || (Input_KeyPressed(KEY_RMETA))) { + mod += 8; + } + + static char buf[64]; + buf[0] = 0; + + bool vt; + int vtCode; + char xtermChar; + + switch (key) { + // vt sequences + case KEY_HOME: vt = true; vtCode = 1; break; + case KEY_INSERT: vt = true; vtCode = 2; break; + case KEY_DELETE: vt = true; vtCode = 3; break; + case KEY_END: vt = true; vtCode = 4; break; + case KEY_PAGE_UP: vt = true; vtCode = 5; break; + case KEY_PAGE_DOWN: vt = true; vtCode = 6; break; + case KEY_F1: vt = true; vtCode = 11; break; + case KEY_F2: vt = true; vtCode = 12; break; + case KEY_F3: vt = true; vtCode = 13; break; + case KEY_F4: vt = true; vtCode = 14; break; + case KEY_F5: vt = true; vtCode = 15; break; + case KEY_F6: vt = true; vtCode = 17; break; + case KEY_F7: vt = true; vtCode = 18; break; + case KEY_F8: vt = true; vtCode = 19; break; + case KEY_F9: vt = true; vtCode = 20; break; + case KEY_F10: vt = true; vtCode = 21; break; + case KEY_F11: vt = true; vtCode = 23; break; + case KEY_F12: vt = true; vtCode = 24; break; + + // xterm sequences + case KEY_UP: vt = false; xtermChar = 'A'; break; + case KEY_DOWN: vt = false; xtermChar = 'B'; break; + case KEY_RIGHT: vt = false; xtermChar = 'C'; break; + case KEY_LEFT: vt = false; xtermChar = 'D'; break; + + default: return buf; + } + + if (vt) { + if (mod == 1) { + snprintf(buf, sizeof(buf), "\x1b[%d~", vtCode); + } + else { + snprintf(buf, sizeof(buf), "\x1b[%d;%d~", vtCode, mod); + } + } + else { + if (mod == 1) { + snprintf(buf, sizeof(buf), "\x1b[%c", xtermChar); + } + else { + snprintf(buf, sizeof(buf), "\x1b[%d%c", mod, xtermChar); + } + } + + return buf; +} + static void SendInput(Interpreter* p_this, Terminal* terminal, Event* e) { Vt100* this = (Vt100*) p_this->data; switch (e->type) { case EVENT_KEY_DOWN: { - const char* seq = NULL; + const char* seq = KeyToSequence(e->key.key); - switch (e->key.key) { - case KEY_RETURN: seq = "\n"; break; - default: break; - } - - if (seq) { - for (size_t i = 0; seq[i]; ++ i) { - SysTerm_WriteByte(&terminal->term, seq[i]); - } + for (size_t i = 0; seq[i]; ++ i) { + SysTerm_WriteByte(&terminal->term, seq[i]); } break; } case EVENT_TEXT_INPUT: { - for (size_t i = 0; e->textInput.input[i]; ++ i) { - SysTerm_WriteByte(&terminal->term, e->textInput.input[i]); + if (Input_KeyPressed(KEY_LALT)) { + SysTerm_WriteByte(&terminal->term, '\x1b'); } + + UChar ch = e->textInput.input[0]; + + SysTerm_WriteByte(&terminal->term, (char) ch); break; } default: break; @@ -71,36 +170,40 @@ char** parts = Split(str, &num, ';'); switch (ch) { case 'A': { // move cursor up # lines - if (num < 1) return; + int amount = 1; + if (num >= 1) amount = atoi(parts[0]); - terminal->cursor.y -= atoi(parts[0]); + terminal->cursor.y -= amount; if (terminal->cursor.y < 0) { terminal->cursor.y = 0; } break; } case 'B': { // move cursor down # lines - if (num < 1) return; + int amount = 1; + if (num >= 1) amount = atoi(parts[0]); - terminal->cursor.y += atoi(parts[0]); + terminal->cursor.y += amount; if (terminal->cursor.y >= terminal->buffer.height) { terminal->cursor.y = terminal->buffer.height - 1; } break; } case 'C': { // move cursor right # columns - if (num < 1) return; + int amount = 1; + if (num >= 1) amount = atoi(parts[0]); - terminal->cursor.x += atoi(parts[0]); + terminal->cursor.x += amount; if (terminal->cursor.x >= terminal->buffer.width) { terminal->cursor.x = terminal->buffer.width - 1; } break; } case 'D': { // move cursor left # columns - if (num < 1) return; + int amount = 1; + if (num >= 1) amount = atoi(parts[0]); - terminal->cursor.x -= atoi(parts[0]); + terminal->cursor.x -= amount; if (terminal->cursor.x < 0) { terminal->cursor.x = 0; } @@ -152,6 +255,7 @@ break; } case 2: { Buffer_Clear(&terminal->buffer); + terminal->cursor = (Vec2) {0, 0}; break; } } @@ -308,6 +412,7 @@ case 1002: break; // TODO: use cell motion mouse tracking case 1003: break; // TODO: use all motion mouse tracking case 1048: break; // TODO: save cursor case 1049: break; // TODO: save cursor & use alternate screen buffer + case 2004: break; // TODO: bracketed paste mode default: printf("Unsupported: %dh\n", param); } break; @@ -329,6 +434,7 @@ case 1002: break; // TODO: do not use cell motion mouse tracking case 1003: break; // TODO: do not use all motion mouse tracking case 1048: break; // TODO: restore cursor case 1049: break; // TODO: restore cursor & use normal screen buffer + case 2004: break; // TODO: bracketed paste mode default: printf("Unsupported: %dl\n", param); } break; diff --git a/source/keyboard.c b/source/keyboard.c index e64afd863e5cda1be66f554700b3f05b0d53327f..2fd03a47d7eaf21efbc65d7aed461fd9dd1db98c 100644 --- a/source/keyboard.c +++ b/source/keyboard.c @@ -3,102 +3,110 @@ #include "keyboard.h" // TODO: this thing has missing values static const char* keyTable[] = { - /* 0 */ /* KEY_NONE */ "None", - /* 1 */ /* KEY_A */ "A", - /* 2 */ /* KEY_B */ "B", - /* 3 */ /* KEY_C */ "C", - /* 4 */ /* KEY_D */ "D", - /* 5 */ /* KEY_E */ "E", - /* 6 */ /* KEY_F */ "F", - /* 7 */ /* KEY_G */ "G", - /* 8 */ /* KEY_H */ "H", - /* 9 */ /* KEY_I */ "I", - /* 10 */ /* KEY_J */ "J", - /* 11 */ /* KEY_K */ "K", - /* 12 */ /* KEY_L */ "L", - /* 13 */ /* KEY_M */ "M", - /* 14 */ /* KEY_N */ "N", - /* 15 */ /* KEY_O */ "O", - /* 16 */ /* KEY_P */ "P", - /* 17 */ /* KEY_Q */ "Q", - /* 18 */ /* KEY_R */ "R", - /* 19 */ /* KEY_S */ "S", - /* 20 */ /* KEY_T */ "T", - /* 21 */ /* KEY_U */ "U", - /* 22 */ /* KEY_V */ "V", - /* 23 */ /* KEY_W */ "W", - /* 24 */ /* KEY_X */ "X", - /* 25 */ /* KEY_Y */ "Y", - /* 26 */ /* KEY_Z */ "Z", - /* 27 */ /* KEY_0 */ "0", - /* 28 */ /* KEY_1 */ "1", - /* 29 */ /* KEY_2 */ "2", - /* 30 */ /* KEY_3 */ "3", - /* 31 */ /* KEY_4 */ "4", - /* 32 */ /* KEY_5 */ "5", - /* 33 */ /* KEY_6 */ "6", - /* 34 */ /* KEY_7 */ "7", - /* 35 */ /* KEY_8 */ "8", - /* 36 */ /* KEY_9 */ "9", - /* 37 */ /* KEY_RETURN */ "Return", - /* 38 */ /* KEY_ESCAPE */ "Escape", - /* 39 */ /* KEY_BACKSPACE */ "Backspace", - /* 40 */ /* KEY_TAB */ "Tab", - /* 41 */ /* KEY_SPACE */ "Space", - /* 42 */ /* KEY_MINUS */ "Minus", - /* 43 */ /* KEY_EQUALS */ "Equals", - /* 44 */ /* KEY_LEFT_BRACKET */ "Left bracket", - /* 45 */ /* KEY_RIGHT_BRACKET */ "Right bracket", - /* 46 */ /* KEY_BACKSLASH */ "Backslash", - /* 47 */ /* KEY_SEMICOLON */ "Semicolon", - /* 48 */ /* KEY_APOSTROPHE */ "Apostrophe", - /* 49 */ /* KEY_GRAVE */ "Grave", - /* 50 */ /* KEY_COMMA */ "Comma", - /* 51 */ /* KEY_PERIOD */ "Period", - /* 52 */ /* KEY_SLASH */ "Slash", - /* 53 */ /* KEY_CAPS_LOCK */ "Caps lock", - /* 54 */ /* KEY_F1 */ "F1", - /* 55 */ /* KEY_F2 */ "F2", - /* 56 */ /* KEY_F3 */ "F3", - /* 57 */ /* KEY_F4 */ "F4", - /* 58 */ /* KEY_F5 */ "F5", - /* 59 */ /* KEY_F6 */ "F6", - /* 60 */ /* KEY_F7 */ "F7", - /* 61 */ /* KEY_F8 */ "F8", - /* 62 */ /* KEY_F9 */ "F9", - /* 63 */ /* KEY_F10 */ "F10", - /* 64 */ /* KEY_F11 */ "F11", - /* 65 */ /* KEY_F12 */ "F12", - /* 66 */ /* KEY_PRINT_SCREEN */ "Print screen", - /* 67 */ /* KEY_SCROLL_LOCK */ "Scroll lock", - /* 68 */ /* KEY_PAUSE */ "Pause", - /* 69 */ /* KEY_INSERT */ "Insert", - /* 70 */ /* KEY_HOME */ "Home", - /* 71 */ /* KEY_PAGE_UP */ "Page up", - /* 72 */ /* KEY_PAGE_DOWN */ "Page down", - /* 73 */ /* KEY_DELETE */ "Delete", - /* 74 */ /* KEY_END */ "End", - /* 75 */ /* KEY_RIGHT */ "Right arrow", - /* 76 */ /* KEY_LEFT */ "Left arrow", - /* 77 */ /* KEY_DOWN */ "Down arrow", - /* 78 */ /* KEY_UP */ "Up arrow", - /* 79 */ /* KEY_NUM_LOCK */ "Num lock", - /* 80 */ /* KEY_NP_DIVIDE */ "Numpad divide", - /* 81 */ /* KEY_NP_MULTIPLY */ "Numpad multiply", - /* 82 */ /* KEY_NP_MINUS */ "Numpad minus", - /* 83 */ /* KEY_NP_PLUS */ "Numpad plus", - /* 84 */ /* KEY_NP_ENTER */ "Numpad enter", - /* 85 */ /* KEY_NP_0 */ "Numpad 0", - /* 86 */ /* KEY_NP_1 */ "Numpad 1", - /* 87 */ /* KEY_NP_2 */ "Numpad 2", - /* 88 */ /* KEY_NP_3 */ "Numpad 3", - /* 89 */ /* KEY_NP_4 */ "Numpad 4", - /* 90 */ /* KEY_NP_5 */ "Numpad 5", - /* 91 */ /* KEY_NP_6 */ "Numpad 6", - /* 92 */ /* KEY_NP_7 */ "Numpad 7", - /* 93 */ /* KEY_NP_8 */ "Numpad 8", - /* 94 */ /* KEY_NP_9 */ "Numpad 9", - /* 95 */ /* KEY_NP_PERIOD */ "Numpad period" + /* 0 */ /* KEY_NONE */ "None", + /* 1 */ /* KEY_A */ "A", + /* 2 */ /* KEY_B */ "B", + /* 3 */ /* KEY_C */ "C", + /* 4 */ /* KEY_D */ "D", + /* 5 */ /* KEY_E */ "E", + /* 6 */ /* KEY_F */ "F", + /* 7 */ /* KEY_G */ "G", + /* 8 */ /* KEY_H */ "H", + /* 9 */ /* KEY_I */ "I", + /* 10 */ /* KEY_J */ "J", + /* 11 */ /* KEY_K */ "K", + /* 12 */ /* KEY_L */ "L", + /* 13 */ /* KEY_M */ "M", + /* 14 */ /* KEY_N */ "N", + /* 15 */ /* KEY_O */ "O", + /* 16 */ /* KEY_P */ "P", + /* 17 */ /* KEY_Q */ "Q", + /* 18 */ /* KEY_R */ "R", + /* 19 */ /* KEY_S */ "S", + /* 20 */ /* KEY_T */ "T", + /* 21 */ /* KEY_U */ "U", + /* 22 */ /* KEY_V */ "V", + /* 23 */ /* KEY_W */ "W", + /* 24 */ /* KEY_X */ "X", + /* 25 */ /* KEY_Y */ "Y", + /* 26 */ /* KEY_Z */ "Z", + /* 27 */ /* KEY_0 */ "0", + /* 28 */ /* KEY_1 */ "1", + /* 29 */ /* KEY_2 */ "2", + /* 30 */ /* KEY_3 */ "3", + /* 31 */ /* KEY_4 */ "4", + /* 32 */ /* KEY_5 */ "5", + /* 33 */ /* KEY_6 */ "6", + /* 34 */ /* KEY_7 */ "7", + /* 35 */ /* KEY_8 */ "8", + /* 36 */ /* KEY_9 */ "9", + /* 37 */ /* KEY_RETURN */ "Return", + /* 38 */ /* KEY_ESCAPE */ "Escape", + /* 39 */ /* KEY_BACKSPACE */ "Backspace", + /* 40 */ /* KEY_TAB */ "Tab", + /* 41 */ /* KEY_SPACE */ "Space", + /* 42 */ /* KEY_MINUS */ "Minus", + /* 43 */ /* KEY_EQUALS */ "Equals", + /* 44 */ /* KEY_LEFT_BRACKET */ "Left bracket", + /* 45 */ /* KEY_RIGHT_BRACKET */ "Right bracket", + /* 46 */ /* KEY_BACKSLASH */ "Backslash", + /* 47 */ /* KEY_SEMICOLON */ "Semicolon", + /* 48 */ /* KEY_APOSTROPHE */ "Apostrophe", + /* 49 */ /* KEY_GRAVE */ "Grave", + /* 50 */ /* KEY_COMMA */ "Comma", + /* 51 */ /* KEY_PERIOD */ "Period", + /* 52 */ /* KEY_SLASH */ "Slash", + /* 53 */ /* KEY_CAPS_LOCK */ "Caps lock", + /* 54 */ /* KEY_F1 */ "F1", + /* 55 */ /* KEY_F2 */ "F2", + /* 56 */ /* KEY_F3 */ "F3", + /* 57 */ /* KEY_F4 */ "F4", + /* 58 */ /* KEY_F5 */ "F5", + /* 59 */ /* KEY_F6 */ "F6", + /* 60 */ /* KEY_F7 */ "F7", + /* 61 */ /* KEY_F8 */ "F8", + /* 62 */ /* KEY_F9 */ "F9", + /* 63 */ /* KEY_F10 */ "F10", + /* 64 */ /* KEY_F11 */ "F11", + /* 65 */ /* KEY_F12 */ "F12", + /* 66 */ /* KEY_PRINT_SCREEN */ "Print screen", + /* 67 */ /* KEY_SCROLL_LOCK */ "Scroll lock", + /* 68 */ /* KEY_PAUSE */ "Pause", + /* 69 */ /* KEY_INSERT */ "Insert", + /* 70 */ /* KEY_HOME */ "Home", + /* 71 */ /* KEY_PAGE_UP */ "Page up", + /* 72 */ /* KEY_PAGE_DOWN */ "Page down", + /* 73 */ /* KEY_DELETE */ "Delete", + /* 74 */ /* KEY_END */ "End", + /* 75 */ /* KEY_RIGHT */ "Right arrow", + /* 76 */ /* KEY_LEFT */ "Left arrow", + /* 77 */ /* KEY_DOWN */ "Down arrow", + /* 78 */ /* KEY_UP */ "Up arrow", + /* 79 */ /* KEY_NUM_LOCK */ "Num lock", + /* 80 */ /* KEY_NP_DIVIDE */ "Numpad divide", + /* 81 */ /* KEY_NP_MULTIPLY */ "Numpad multiply", + /* 82 */ /* KEY_NP_MINUS */ "Numpad minus", + /* 83 */ /* KEY_NP_PLUS */ "Numpad plus", + /* 84 */ /* KEY_NP_ENTER */ "Numpad enter", + /* 85 */ /* KEY_NP_0 */ "Numpad 0", + /* 86 */ /* KEY_NP_1 */ "Numpad 1", + /* 87 */ /* KEY_NP_2 */ "Numpad 2", + /* 88 */ /* KEY_NP_3 */ "Numpad 3", + /* 89 */ /* KEY_NP_4 */ "Numpad 4", + /* 90 */ /* KEY_NP_5 */ "Numpad 5", + /* 91 */ /* KEY_NP_6 */ "Numpad 6", + /* 92 */ /* KEY_NP_7 */ "Numpad 7", + /* 93 */ /* KEY_NP_8 */ "Numpad 8", + /* 94 */ /* KEY_NP_9 */ "Numpad 9", + /* 95 */ /* KEY_NP_PERIOD */ "Numpad period", + /* 96 */ /* KEY_LCTRL */ "" "Left control", + /* 97 */ /* KEY_LSHIFT */ "" "Left shift", + /* 98 */ /* KEY_LALT */ "" "Left alt", + /* 99 */ /* KEY_LMETA */ "" "Left meta", + /* 100 */ /* KEY_RCTRL */ "" "Right control", + /* 101 */ /* KEY_RSHIFT */ "" "Right shift", + /* 102 */ /* KEY_RALT */ "" "Right alt", + /* 103 */ /* KEY_RMETA */ "" "Right meta", }; const char* Key_ToString(Key key) { diff --git a/source/keyboard.h b/source/keyboard.h index 68af91092313b988efa73a849bd574b144b976c1..3052bcc542216a67cb0fb705f4f33ae0f1b4b8d5 100644 --- a/source/keyboard.h +++ b/source/keyboard.h @@ -109,6 +109,15 @@ KEY_NP_8 = 93, KEY_NP_9 = 94, KEY_NP_PERIOD = 95, + KEY_LCTRL = 96, + KEY_LSHIFT = 97, + KEY_LALT = 98, + KEY_LMETA = 99, + KEY_RCTRL = 100, + KEY_RSHIFT = 101, + KEY_RALT = 102, + KEY_RMETA = 103, + KEY_AMOUNT } Key;