From d0fd75d6731fdfeb4cf3066558da18f21eb1d10f Mon Sep 17 00:00:00 2001 From: Anton Anikin Date: Mon, 20 Sep 2021 19:35:42 +0800 Subject: [PATCH] initial commit --- .gitignore | 4 + CMakeLists.txt | 13 ++ src/keycode.c | 344 +++++++++++++++++++++++++++++++++++++++++++++++++ src/keycode.h | 52 ++++++++ src/test.c | 9 ++ 5 files changed, 422 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 src/keycode.c create mode 100644 src/keycode.h create mode 100644 src/test.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63cabc0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.kdev4/ +*.kdev4 + +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5ef890d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,13 @@ +project(keycode) + +add_library(keycode STATIC + src/keycode.c +) + +add_executable(keycode_test + src/test.c +) + +target_link_libraries(keycode_test + keycode +) diff --git a/src/keycode.c b/src/keycode.c new file mode 100644 index 0000000..d2ae282 --- /dev/null +++ b/src/keycode.c @@ -0,0 +1,344 @@ +#include "keycode.h" + +#if defined(__linux__) || defined(__APPLE__) +// http://forum.shelek.ru/index.php/topic,9792.0.html + +#include +#include +#include +#include +#include + +void +save_termsettings(struct termios *original_settings) +{ + // man tcsetattr + struct termios new_settings; + + tcgetattr(0, original_settings); + new_settings = *original_settings; + + // Disable canonical mode, and set buffer size to 1 byte + new_settings.c_lflag &= (~ICANON); + //new_settings.c_lflag &= ICANON; + + // Timeout in deciseconds for noncanonical read + new_settings.c_cc[VTIME] = 0; + + // Minimum number of characters for noncanonical read + new_settings.c_cc[VMIN] = 1; + + // Disable echo input characters + new_settings.c_lflag &= ~ECHO; + + tcsetattr(0, TCSANOW, &new_settings); +} + +void +restore_termsettings(const struct termios *original_settings) +{ + tcsetattr(0, TCSANOW, original_settings); +} +#endif + +#if defined(__linux__) +int +keycode() +{ + int buffer[10]; + static struct termios original_settings; + + save_termsettings(&original_settings); + + int len = 1; + int code = 0; + + buffer[0] = getchar(); + if (buffer[0] == KEY_ESC) { + //printf("ESC in\n"); + struct termios current_settings; + tcgetattr(0, ¤t_settings); + + current_settings.c_cc[VMIN] = 0; + tcsetattr(0, TCSANOW, ¤t_settings); + while ((buffer[len] = getchar()) > 0) { + //printf("ESC_go; code = %3d\n", buffer[len]); + len++; + } + clearerr(stdin); + + current_settings.c_cc[VMIN] = 1; + tcsetattr(0, TCSANOW, ¤t_settings); + } + + if (len == 1) { + code = buffer[0]; + } else { + // ugly code + if ((len == 3) && (buffer[1] == 91) && (buffer[2] == 65)) code = KEY_UP; + if ((len == 3) && (buffer[1] == 91) && (buffer[2] == 66)) code = KEY_DOWN; + if ((len == 3) && (buffer[1] == 91) && (buffer[2] == 67)) code = KEY_RIGHT; + if ((len == 3) && (buffer[1] == 91) && (buffer[2] == 68)) code = KEY_LEFT; + + if ((len == 3) && (buffer[1] == 91) && (buffer[2] == 72)) code = KEY_HOME; + if ((len == 3) && (buffer[1] == 91) && (buffer[2] == 70)) code = KEY_END; + + if ((len == 4) && (buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 126)) code = KEY_INS; + if ((len == 4) && (buffer[1] == 91) && (buffer[2] == 51) && (buffer[3] == 126)) code = KEY_DEL; + + if ((len == 4) && (buffer[1] == 91) && (buffer[2] == 53) && (buffer[3] == 126)) code = KEY_PGUP; + if ((len == 4) && (buffer[1] == 91) && (buffer[2] == 54) && (buffer[3] == 126)) code = KEY_PGDN; + + if ((len == 3) && (buffer[1] == 79) && (buffer[2] == 80)) code = KEY_F1; + if ((len == 3) && (buffer[1] == 79) && (buffer[2] == 81)) code = KEY_F2; + if ((len == 3) && (buffer[1] == 79) && (buffer[2] == 82)) code = KEY_F3; + if ((len == 3) && (buffer[1] == 79) && (buffer[2] == 83)) code = KEY_F4; + + if ((len == 5) && (buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 53) && (buffer[4] == 126)) code = KEY_F5; + if ((len == 5) && (buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 55) && (buffer[4] == 126)) code = KEY_F6; + if ((len == 5) && (buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 56) && (buffer[4] == 126)) code = KEY_F7; + if ((len == 5) && (buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 57) && (buffer[4] == 126)) code = KEY_F8; + + if ((len == 5) && (buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 48) && (buffer[4] == 126)) code = KEY_F9; + if ((len == 5) && (buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 49) && (buffer[4] == 126)) code = KEY_F10; + if ((len == 5) && (buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 51) && (buffer[4] == 126)) code = KEY_F11; + if ((len == 5) && (buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 52) && (buffer[4] == 126)) code = KEY_F12; + + /*if (code == 0) { + for (i = 0; i < len; i++) + printf("%d;", buffer[i]); + printf("\n"); + }*/ + } + + restore_termsettings(&original_settings); + + return code; +} +#endif + +#if defined(__APPLE__) + +// http://www.ai.rug.nl/vakinformatie/pas/content/Aria-manual/ArKeyHandler_8cpp-source.html + +int +keycode() +{ + static struct termios original_settings; + save_termsettings(&original_settings); + + int buffer[10]; + char len = 1; + int code = -1; + + buffer[0] = getchar(); + + if (buffer[0] == KEY_ESC) { + while (1) { + buffer[len] = getchar(); + len++; + + if (len == 2) { + if (buffer[1] == KEY_ESC) + code = KEY_ESC; + else if ((buffer[1] != 79) && (buffer[1] != 91)) + code = 0; + } else if (len == 3) { + if ((buffer[1] == 91) && (buffer[2] == 65)) code = KEY_UP; + if ((buffer[1] == 91) && (buffer[2] == 66)) code = KEY_DOWN; + if ((buffer[1] == 91) && (buffer[2] == 67)) code = KEY_RIGHT; + if ((buffer[1] == 91) && (buffer[2] == 68)) code = KEY_LEFT; + + if ((buffer[1] == 91) && (buffer[2] == 72)) code = KEY_HOME; + if ((buffer[1] == 91) && (buffer[2] == 70)) code = KEY_END; + + if ((buffer[1] == 79) && (buffer[2] == 80)) code = KEY_F1; + if ((buffer[1] == 79) && (buffer[2] == 81)) code = KEY_F2; + if ((buffer[1] == 79) && (buffer[2] == 82)) code = KEY_F3; + if ((buffer[1] == 79) && (buffer[2] == 83)) code = KEY_F4; + } else if (len == 4) { + if ((buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 126)) code = KEY_INS; + if ((buffer[1] == 91) && (buffer[2] == 51) && (buffer[3] == 126)) code = KEY_DEL; + + if ((buffer[1] == 91) && (buffer[2] == 53) && (buffer[3] == 126)) code = KEY_PGUP; + if ((buffer[1] == 91) && (buffer[2] == 54) && (buffer[3] == 126)) code = KEY_PGDN; + } else if (len == 5) { + if ((buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 53) && (buffer[4] == 126)) code = KEY_F5; + if ((buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 55) && (buffer[4] == 126)) code = KEY_F6; + if ((buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 56) && (buffer[4] == 126)) code = KEY_F7; + if ((buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 57) && (buffer[4] == 126)) code = KEY_F8; + + if ((buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 48) && (buffer[4] == 126)) code = KEY_F9; + if ((buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 49) && (buffer[4] == 126)) code = KEY_F10; + if ((buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 51) && (buffer[4] == 126)) code = KEY_F11; + if ((buffer[1] == 91) && (buffer[2] == 50) && (buffer[3] == 52) && (buffer[4] == 126)) code = KEY_F12; + } else + code = 0; + + if (code >= 0) break; + } + } + + if (len == 1) { + code = buffer[0]; + } + + restore_termsettings(&original_settings); + + return code; +} + +#endif + +#if defined(_WIN32) + +// http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1048384015&id=1043284392 + +#include + +int +getkeycode() +{ + int code = -1; + int key = getch(); + + if (key == 0) { + key = getch(); + //printf("(%3d;%3d) ", 0, key); + + if (key == 59) code = KEY_F1; + if (key == 60) code = KEY_F2; + if (key == 61) code = KEY_F3; + if (key == 62) code = KEY_F4; + if (key == 63) code = KEY_F5; + if (key == 64) code = KEY_F6; + if (key == 65) code = KEY_F7; + if (key == 66) code = KEY_F8; + if (key == 67) code = KEY_F9; + if (key == 68) code = KEY_F10; + } else if (key == 224) { + key = keycode(); + //printf("(%3d;%3d) ", 224, key); + + if (key == 133) code = KEY_F11; + if (key == 134) code = KEY_F12; + + if (key == 82) code = KEY_INS; + if (key == 83) code = KEY_DEL; + + if (key == 71) code = KEY_HOME; + if (key == 79) code = KEY_END; + + if (key == 73) code = KEY_PGUP; + if (key == 81) code = KEY_PGDN; + + if (key == 72) code = KEY_UP; + if (key == 80) code = KEY_DOWN; + if (key == 75) code = KEY_LEFT; + if (key == 77) code = KEY_RIGHT; + } else { + code = key; + } + + return code; +} + +#endif + +void +test_keycodes() +{ + printf("getkeycode() test; press 'q' for exit\n"); + printf("Press 'q' for exit\n\n"); + + int code; + while ((code = keycode()) != 'q') { + switch (code) { + case KEY_UP : + printf("KEY_UP "); + break; + case KEY_DOWN : + printf("KEY_DOWN "); + break; + case KEY_RIGHT: + printf("KEY_RIGHT "); + break; + case KEY_LEFT : + printf("KEY_LEFT "); + break; + case KEY_TAB : + printf("KEY_TAB "); + break; + case KEY_BS : + printf("KEY_BS "); + break; + case KEY_SPACE: + printf("KEY_SPACE "); + break; + case KEY_INS : + printf("KEY_INS "); + break; + case KEY_DEL : + printf("KEY_DEL "); + break; + case KEY_ESC : + printf("KEY_ESC "); + break; + case KEY_ENTER: + printf("KEY_ENTER "); + break; + case KEY_F1 : + printf("KEY_F1 "); + break; + case KEY_F2 : + printf("KEY_F2 "); + break; + case KEY_F3 : + printf("KEY_F3 "); + break; + case KEY_F4 : + printf("KEY_F4 "); + break; + case KEY_F5 : + printf("KEY_F5 "); + break; + case KEY_F6 : + printf("KEY_F6 "); + break; + case KEY_F7 : + printf("KEY_F7 "); + break; + case KEY_F8 : + printf("KEY_F8 "); + break; + case KEY_F9 : + printf("KEY_F9 "); + break; + case KEY_F10: + printf("KEY_F10 "); + break; + case KEY_F11: + printf("KEY_F11 "); + break; + case KEY_F12: + printf("KEY_F12 "); + break; + case KEY_HOME : + printf("KEY_HOME "); + break; + case KEY_END : + printf("KEY_END "); + break; + case KEY_PGUP : + printf("KEY_PGUP "); + break; + case KEY_PGDN : + printf("KEY_PGDN "); + break; + default: + printf("%d - '%c'", code, code); + } + printf("\n"); + } + printf("\n"); +} diff --git a/src/keycode.h b/src/keycode.h new file mode 100644 index 0000000..89032a3 --- /dev/null +++ b/src/keycode.h @@ -0,0 +1,52 @@ +#pragma once + +int +keycode(); + +void +test_keycodes(); + +// key codes ========================================== + +#define KEY_TAB 9 +#define KEY_ESC 27 +#define KEY_SPACE 32 + +#if defined(_WIN32) + +#define KEY_BS 8 +#define KEY_ENTER 13 + +#elif defined(__linux__) || defined(__APPLE__) + +#define KEY_BS 127 +#define KEY_ENTER 10 + +#endif + +#define KEY_INS 1000 +#define KEY_DEL 1001 + +#define KEY_UP 1002 +#define KEY_DOWN 1003 +#define KEY_RIGHT 1004 +#define KEY_LEFT 1005 + +#define KEY_F1 1006 +#define KEY_F2 1007 +#define KEY_F3 1008 +#define KEY_F4 1009 +#define KEY_F5 1010 +#define KEY_F6 1011 +#define KEY_F7 1012 +#define KEY_F8 1013 +#define KEY_F9 1014 +#define KEY_F10 1015 +#define KEY_F11 1016 +#define KEY_F12 1017 + +#define KEY_HOME 1018 +#define KEY_END 1019 + +#define KEY_PGUP 1020 +#define KEY_PGDN 1021 diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..449dc69 --- /dev/null +++ b/src/test.c @@ -0,0 +1,9 @@ +#include "keycode.h" + +int +main(int /*argc*/, char** /*argv*/) +{ + test_keycodes(); + + return 0; +}