aboutsummaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
authorverdant <i@glowisle.me>2026-05-16 21:21:02 +0800
committerverdant <i@glowisle.me>2026-05-16 21:21:02 +0800
commit0f45252d3f46d28ad99793eb875087462504defb (patch)
tree54e86af9d10af4794587ed88d6b0536d4cc7b426 /main.c
parent2d6ad961a01a6f72150df54e9df57dae8b79cbcc (diff)
downloadkl-0f45252d3f46d28ad99793eb875087462504defb.tar.gz
kl-0f45252d3f46d28ad99793eb875087462504defb.zip
Initial commit
Diffstat (limited to 'main.c')
-rw-r--r--main.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..8faac24
--- /dev/null
+++ b/main.c
@@ -0,0 +1,238 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <termios.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#define PROGRAM_NAME "kl"
+
+static struct termios original_term;
+const char *key_names[256] = {0};
+
+void init_key_names() {
+ key_names[KEY_Q] = "Q";
+ key_names[KEY_W] = "W";
+ key_names[KEY_E] = "E";
+ key_names[KEY_R] = "R";
+ key_names[KEY_T] = "T";
+ key_names[KEY_Y] = "Y";
+ key_names[KEY_U] = "U";
+ key_names[KEY_I] = "I";
+ key_names[KEY_O] = "O";
+ key_names[KEY_P] = "P";
+ key_names[KEY_A] = "A";
+ key_names[KEY_S] = "S";
+ key_names[KEY_D] = "D";
+ key_names[KEY_F] = "F";
+ key_names[KEY_G] = "G";
+ key_names[KEY_H] = "H";
+ key_names[KEY_J] = "J";
+ key_names[KEY_K] = "K";
+ key_names[KEY_L] = "L";
+ key_names[KEY_Z] = "Z";
+ key_names[KEY_X] = "X";
+ key_names[KEY_C] = "C";
+ key_names[KEY_V] = "V";
+ key_names[KEY_B] = "B";
+ key_names[KEY_N] = "N";
+ key_names[KEY_M] = "M";
+
+ key_names[KEY_1] = "1";
+ key_names[KEY_2] = "2";
+ key_names[KEY_3] = "3";
+ key_names[KEY_4] = "4";
+ key_names[KEY_5] = "5";
+ key_names[KEY_6] = "6";
+ key_names[KEY_7] = "7";
+ key_names[KEY_8] = "8";
+ key_names[KEY_9] = "9";
+ key_names[KEY_0] = "0";
+
+ key_names[KEY_MINUS] = "-";
+ key_names[KEY_EQUAL] = "=";
+ key_names[KEY_LEFTBRACE] = "[";
+ key_names[KEY_RIGHTBRACE] = "]";
+ key_names[KEY_SEMICOLON] = ";";
+ key_names[KEY_APOSTROPHE] = "'";
+ key_names[KEY_GRAVE] = "`";
+ key_names[KEY_BACKSLASH] = "\\";
+ key_names[KEY_COMMA] = ",";
+ key_names[KEY_DOT] = ".";
+ key_names[KEY_SLASH] = "/";
+ key_names[KEY_SPACE] = "<SPACE>";
+
+ key_names[KEY_ESC] = "<ESC>";
+ key_names[KEY_BACKSPACE] = "<BACKSPACE>";
+ key_names[KEY_TAB] = "<TAB>";
+ key_names[KEY_ENTER] = "<ENTER>";
+ key_names[KEY_LEFTSHIFT] = "<L_SHIFT>";
+ key_names[KEY_RIGHTSHIFT] = "<R_SHIFT>";
+ key_names[KEY_LEFTCTRL] = "<L_CTRL>";
+ key_names[KEY_RIGHTCTRL] = "<R_CTRL>";
+ key_names[KEY_LEFTALT] = "<L_ALT>";
+ key_names[KEY_RIGHTALT] = "<R_ALT>";
+ key_names[KEY_LEFTMETA] = "<L_META>";
+ key_names[KEY_RIGHTMETA] = "<R_META>";
+ key_names[KEY_CAPSLOCK] = "<CAPSLOCK>";
+ key_names[KEY_NUMLOCK] = "<NUMLOCK>";
+ key_names[KEY_SCROLLLOCK] = "<SCROLLLOCK>";
+
+ key_names[KEY_F1] = "<F1>";
+ key_names[KEY_F2] = "<F2>";
+ key_names[KEY_F3] = "<F3>";
+ key_names[KEY_F4] = "<F4>";
+ key_names[KEY_F5] = "<F5>";
+ key_names[KEY_F6] = "<F6>";
+ key_names[KEY_F7] = "<F7>";
+ key_names[KEY_F8] = "<F8>";
+ key_names[KEY_F9] = "<F9>";
+ key_names[KEY_F10] = "<F10>";
+ key_names[KEY_F11] = "<F11>";
+ key_names[KEY_F12] = "<F12>";
+ key_names[KEY_F13] = "<F13>";
+ key_names[KEY_F14] = "<F14>";
+ key_names[KEY_F15] = "<F15>";
+ key_names[KEY_F16] = "<F16>";
+ key_names[KEY_F17] = "<F17>";
+ key_names[KEY_F18] = "<F18>";
+ key_names[KEY_F19] = "<F19>";
+ key_names[KEY_F20] = "<F20>";
+ key_names[KEY_F21] = "<F21>";
+ key_names[KEY_F22] = "<F22>";
+ key_names[KEY_F23] = "<F23>";
+ key_names[KEY_F24] = "<F24>";
+
+ key_names[KEY_KP0] = "<KP0>";
+ key_names[KEY_KP1] = "<KP1>";
+ key_names[KEY_KP2] = "<KP2>";
+ key_names[KEY_KP3] = "<KP3>";
+ key_names[KEY_KP4] = "<KP4>";
+ key_names[KEY_KP5] = "<KP5>";
+ key_names[KEY_KP6] = "<KP6>";
+ key_names[KEY_KP7] = "<KP7>";
+ key_names[KEY_KP8] = "<KP8>";
+ key_names[KEY_KP9] = "<KP9>";
+ key_names[KEY_KPDOT] = "<KP.>";
+ key_names[KEY_KPCOMMA] = "<KP,>";
+ key_names[KEY_KPENTER] = "<KPENTER>";
+ key_names[KEY_KPMINUS] = "<KP->";
+ key_names[KEY_KPPLUS] = "<KP+>";
+ key_names[KEY_KPSLASH] = "<KP/>";
+ key_names[KEY_KPASTERISK] = "<KP*>";
+ key_names[KEY_KPEQUAL] = "<KP=>";
+
+ key_names[KEY_UP] = "<UP>";
+ key_names[KEY_DOWN] = "<DOWN>";
+ key_names[KEY_LEFT] = "<LEFT>";
+ key_names[KEY_RIGHT] = "<RIGHT>";
+ key_names[KEY_HOME] = "<HOME>";
+ key_names[KEY_END] = "<END>";
+ key_names[KEY_PAGEUP] = "<PAGEUP>";
+ key_names[KEY_PAGEDOWN] = "<PAGEDOWN>";
+ key_names[KEY_INSERT] = "<INSERT>";
+ key_names[KEY_DELETE] = "<DELETE>";
+
+ key_names[KEY_MUTE] = "<MUTE>";
+ key_names[KEY_VOLUMEDOWN] = "<VOLUMEDOWN>";
+ key_names[KEY_VOLUMEUP] = "<VOLUMEUP>";
+ key_names[KEY_POWER] = "<POWER>";
+ key_names[KEY_SLEEP] = "<SLEEP>";
+ key_names[KEY_WAKEUP] = "<WAKEUP>";
+ key_names[KEY_PLAY] = "<PLAY>";
+ key_names[KEY_PAUSE] = "<PAUSE>";
+ key_names[KEY_PLAYPAUSE] = "<PLAYPAUSE>";
+ key_names[KEY_STOPCD] = "<STOP>";
+ key_names[KEY_PREVIOUSSONG] = "<PREVIOUS>";
+ key_names[KEY_NEXTSONG] = "<NEXT>";
+ key_names[KEY_REWIND] = "<REWIND>";
+ key_names[KEY_FASTFORWARD] = "<FASTFORWARD>";
+ key_names[KEY_RECORD] = "<RECORD>";
+ key_names[KEY_EJECTCD] = "<EJECT>";
+
+ key_names[KEY_SYSRQ] = "<SYSRQ>";
+ key_names[KEY_PAUSE] = "<PAUSE>";
+ key_names[KEY_MENU] = "<MENU>";
+ key_names[KEY_CALC] = "<CALC>";
+ key_names[KEY_MAIL] = "<MAIL>";
+ key_names[KEY_WWW] = "<WWW>";
+ key_names[KEY_SEARCH] = "<SEARCH>";
+ key_names[KEY_BACK] = "<BACK>";
+ key_names[KEY_FORWARD] = "<FORWARD>";
+ key_names[KEY_REFRESH] = "<REFRESH>";
+ key_names[KEY_STOP] = "<STOP>";
+ key_names[KEY_COPY] = "<COPY>";
+ key_names[KEY_CUT] = "<CUT>";
+ key_names[KEY_PASTE] = "<PASTE>";
+ key_names[KEY_UNDO] = "<UNDO>";
+ key_names[KEY_REDO] = "<REDO>";
+ key_names[KEY_FIND] = "<FIND>";
+ key_names[KEY_HELP] = "<HELP>";
+ key_names[KEY_FILE] = "<FILE>";
+ key_names[KEY_SAVE] = "<SAVE>";
+ key_names[KEY_NEW] = "<NEW>";
+ key_names[KEY_OPEN] = "<OPEN>";
+ key_names[KEY_CLOSE] = "<CLOSE>";
+ key_names[KEY_EXIT] = "<EXIT>";
+ key_names[KEY_PRINT] = "<PRINT>";
+ key_names[KEY_BRIGHTNESSDOWN] = "<BRIGHTNESSDOWN>";
+ key_names[KEY_BRIGHTNESSUP] = "<BRIGHTNESSUP>";
+ key_names[KEY_DISPLAY_OFF] = "<DISPLAYOFF>";
+ key_names[KEY_MICMUTE] = "<MICMUTE>";
+ key_names[KEY_WLAN] = "<WLAN>";
+ key_names[KEY_BLUETOOTH] = "<BLUETOOTH>";
+}
+
+void usage() {
+ printf("Usage: %s <EVENT_FILE_PATH>.\n", PROGRAM_NAME);
+}
+
+void disable_term_echo() {
+ struct termios new_setting, init_setting;
+ tcgetattr(0, &init_setting);
+ new_setting = init_setting;
+
+ new_setting.c_lflag&=~ECHO;
+ tcsetattr(0, TCSANOW, &new_setting);
+}
+
+void enable_term_echo() {
+ tcsetattr(0, TCSANOW, &original_term);
+}
+
+int main(int argc, char** argv) {
+ if (argc != 2 || strcmp(argv[1], "--help") == 0) {
+ usage();
+ return -1;
+ }
+
+ disable_term_echo();
+
+ struct input_event ie;
+ int fd = open(argv[1], O_RDONLY);
+
+ if (fd == -1 && errno == EACCES) {
+ printf("Permission denied: please run %s with sudo.\n", PROGRAM_NAME);
+ return -1;
+ }
+
+ init_key_names();
+
+ while (1) {
+ read(fd, &ie, sizeof(ie));
+
+ if (ie.type == EV_KEY && ie.value == 2) {
+ continue;
+ }
+
+ if (key_names[ie.code] != NULL && ie.value == 1) {
+ printf("%s\n", key_names[ie.code]);
+ }
+
+ }
+
+ enable_term_echo();
+ return 0;
+}