Created
February 27, 2026 01:55
-
-
Save scturtle/6e7184176a067ac31c3dd5c31ce2a861 to your computer and use it in GitHub Desktop.
kitty keyboard protocol demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <poll.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <termios.h> | |
| #include <unistd.h> | |
| struct termios orig_termios; | |
| void reset_terminal() { | |
| printf("\033[<u\033[?25h"); // 退出 KKP 并显示光标 | |
| tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios); | |
| fflush(stdout); | |
| } | |
| void set_terminal() { | |
| tcgetattr(STDIN_FILENO, &orig_termios); | |
| atexit(reset_terminal); | |
| struct termios raw = orig_termios; | |
| raw.c_lflag &= ~(ECHO | ICANON | ISIG); | |
| tcsetattr(STDIN_FILENO, TCSANOW, &raw); | |
| printf("\033[?25l\033[>11u"); // 隐藏光标开启 KKP | |
| fflush(stdout); | |
| } | |
| const char *get_mods(int m) { | |
| static char buf[32]; | |
| m -= 1; // modifier = mask + 1 | |
| snprintf(buf, sizeof(buf), "%s%s%s%s", (m & 1) ? "Shift " : "", | |
| (m & 2) ? "Alt " : "", (m & 4) ? "Ctrl " : "", | |
| (m & 8) ? "Super " : ""); | |
| return buf; | |
| } | |
| int main() { | |
| set_terminal(); | |
| printf("Kitty Keyboard Protocol Demo. Press 'q' or 'ESC' to exit.\r\n"); | |
| while (1) { | |
| unsigned char buf[64]; | |
| int n = read(STDIN_FILENO, buf, sizeof(buf) - 1); | |
| if (n <= 0) | |
| continue; | |
| buf[n] = '\0'; | |
| if (buf[0] == 27 && n > 1 && buf[1] == '[') { | |
| int code = 0, mods = 1, event = 1; | |
| char cmd = buf[n - 1]; | |
| const char *evtname[] = {"", "PRESS", "REPEAT", "RELEASE"}; | |
| if (cmd == 'u' || (cmd >= 'A' && cmd <= 'Z')) { | |
| if (sscanf((char *)buf + 2, "%d;%d:%d", &code, &mods, &event) < 3) | |
| if (sscanf((char *)buf + 2, "%d;%d", &code, &mods) < 2) | |
| sscanf((char *)buf + 2, "%d", &code); | |
| if (cmd == 'u') { | |
| printf("[%7s] Key: %-10d | Mods: %s\n", | |
| evtname[event > 3 ? 0 : event], code, get_mods(mods)); | |
| if (code == 'q' || code == 27) | |
| break; | |
| } else if (cmd >= 'A' && cmd <= 'Z') { | |
| const char *arrow[] = {"UP", "DOWN", "RIGHT", "LEFT"}; | |
| printf("[%7s] Key: %-10s | Mods: %s\n", | |
| evtname[event > 3 ? 0 : event], arrow[cmd - 'A'], | |
| get_mods(mods)); | |
| } | |
| } else { | |
| printf("Other CSI: %s\r\n", buf + 1); | |
| } | |
| } else if (buf[0] == 27 && n == 1) { | |
| printf("Legacy ESC pressed.\r\n"); | |
| break; | |
| } else { | |
| printf("Legacy Char: %c (%d)\r\n", buf[0] >= 32 ? buf[0] : '.', buf[0]); | |
| if (buf[0] == 'q') | |
| break; | |
| } | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment