359 lines
12 KiB
C
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, ¤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 {
|
|
/*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");
|
|
}
|