Files
keycode/src/keycode.c
2021-12-26 17:58:31 +08:00

359 lines
12 KiB
C

#include "keycode.h"
#if defined(__linux__) || defined(__APPLE__)
// http://forum.shelek.ru/index.php/topic,9792.0.html
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>
#include <string.h>
#include <unistd.h>
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, &current_settings);
current_settings.c_cc[VMIN] = 0;
tcsetattr(0, TCSANOW, &current_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, &current_settings);
}
if (len == 1) {
code = buffer[0];
} else {
/*if (code == 0) {
printf("len = %d\n", len);
for (int i = 0; i < len; i++) {
printf("%d; ", buffer[i]);
}
printf("\n");
}*/
// 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;
// inside tmux on ubuntu 20.04
if ((len == 4) && (buffer[1] == 91) && (buffer[2] == 49) && (buffer[3] == 126)) code = KEY_HOME;
if ((len == 4) && (buffer[1] == 91) && (buffer[2] == 52) && (buffer[3] == 126)) 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) {
printf("len = %d\n", len);
for (int 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 <conio.h>
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");
}