Created
October 17, 2025 21:17
-
-
Save cnmoro/d31dde5a37506211dd02b7d2158cc9fc to your computer and use it in GitHub Desktop.
Chromebook Linux Remap F-keys to Algr+1,2,3,etc
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
| 1 - Identificar o device | |
| cat /proc/bus/input/devices | |
| Look for something that says "keyboard" in the N: Name= line. In this example, it's "AT Translated Set 2 keyboard". The important part is the Handlers= line—it shows event1, which means the device is /dev/input/event1. | |
| 2 - Validar o dispositivo | |
| sudo evtest | |
| 3 - Atualizar o código C com o device | |
| Linha "input_fd = open("/dev/input/event0", O_RDONLY);" - trocar o eventX | |
| 4 - Build | |
| sudo apt update | |
| sudo apt install build-essential | |
| gcc -o remapper remapper.c | |
| sudo ./remapper # executa | |
| --------------- | |
| Código: | |
| ```remapper.c | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <fcntl.h> | |
| #include <linux/input.h> | |
| #include <linux/uinput.h> | |
| #include <sys/ioctl.h> | |
| int main() { | |
| int input_fd, uinput_fd; | |
| struct input_event ie; | |
| struct uinput_setup usetup; | |
| // Open uinput for creating virtual keyboard | |
| uinput_fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); | |
| if (uinput_fd < 0) { | |
| perror("open /dev/uinput"); | |
| return 1; | |
| } | |
| // Set up virtual device | |
| memset(&usetup, 0, sizeof(usetup)); | |
| usetup.id.bustype = BUS_USB; | |
| usetup.id.vendor = 0x1234; | |
| usetup.id.product = 0x5678; | |
| strcpy(usetup.name, "Keyboard Remapper"); | |
| // Enable key events | |
| ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY); | |
| ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN); | |
| for (int i = 0; i < 256; i++) { | |
| ioctl(uinput_fd, UI_SET_KEYBIT, i); | |
| } | |
| ioctl(uinput_fd, UI_DEV_SETUP, &usetup); | |
| ioctl(uinput_fd, UI_DEV_CREATE); | |
| sleep(1); | |
| // Open input device | |
| input_fd = open("/dev/input/event4", O_RDONLY); | |
| if (input_fd < 0) { | |
| perror("open /dev/input/event4"); | |
| close(uinput_fd); | |
| return 1; | |
| } | |
| printf("Listening for keyboard input. Press Ctrl+C to exit.\n"); | |
| printf("Remapping:\n"); | |
| printf(" AltGr+1 -> F1\n"); | |
| printf(" AltGr+2 -> F2\n"); | |
| printf(" ... (3-9 for F3-F9)\n"); | |
| printf(" AltGr+0 -> F10\n"); | |
| printf(" AltGr+- -> F11\n"); | |
| printf(" AltGr+= -> F12\n"); | |
| int altgr_pressed = 0; | |
| int remapping_active = 0; // Flag to block modifier forwarding | |
| // Mapping table for number keys to F-keys | |
| struct { | |
| int keycode; | |
| int fkey; | |
| } keymap[] = { | |
| {KEY_1, KEY_F1}, | |
| {KEY_2, KEY_F2}, | |
| {KEY_3, KEY_F3}, | |
| {KEY_4, KEY_F4}, | |
| {KEY_5, KEY_F5}, | |
| {KEY_6, KEY_F6}, | |
| {KEY_7, KEY_F7}, | |
| {KEY_8, KEY_F8}, | |
| {KEY_9, KEY_F9}, | |
| {KEY_0, KEY_F10}, | |
| {KEY_MINUS, KEY_F11}, | |
| {KEY_EQUAL, KEY_F12}, | |
| {0, 0} // Sentinel | |
| }; | |
| // Try to grab the device exclusively to prevent key events from propagating | |
| ioctl(input_fd, EVIOCGRAB, 1); | |
| while (1) { | |
| if (read(input_fd, &ie, sizeof(ie)) != sizeof(ie)) { | |
| perror("read"); | |
| break; | |
| } | |
| // Track Right Alt (AltGr) state | |
| if (ie.type == EV_KEY && ie.code == KEY_RIGHTALT) { | |
| altgr_pressed = ie.value; | |
| } | |
| // Check if this is a remappable key combination | |
| if (ie.type == EV_KEY && altgr_pressed) { | |
| int remapped_key = 0; | |
| for (int i = 0; keymap[i].keycode != 0; i++) { | |
| if (ie.code == keymap[i].keycode) { | |
| remapped_key = keymap[i].fkey; | |
| break; | |
| } | |
| } | |
| if (remapped_key) { | |
| if (ie.value == 1) { // Key press | |
| remapping_active = 1; // Block modifier forwarding | |
| // Calculate correct F-key number for display | |
| int fkey_num = 0; | |
| if (remapped_key >= KEY_F1 && remapped_key <= KEY_F12) { | |
| fkey_num = remapped_key - KEY_F1 + 1; | |
| } | |
| printf("Detected AltGr+key, sending F%d\n", fkey_num); | |
| // Send ONLY the F-key press (no modifiers) | |
| struct input_event fkey_ev; | |
| memset(&fkey_ev, 0, sizeof(fkey_ev)); | |
| fkey_ev.type = EV_KEY; | |
| fkey_ev.code = remapped_key; | |
| fkey_ev.value = 1; | |
| write(uinput_fd, &fkey_ev, sizeof(fkey_ev)); | |
| // Sync | |
| fkey_ev.type = EV_SYN; | |
| fkey_ev.code = SYN_REPORT; | |
| fkey_ev.value = 0; | |
| write(uinput_fd, &fkey_ev, sizeof(fkey_ev)); | |
| } else if (ie.value == 2) { // Key repeat | |
| // Forward repeat events as F-key repeats | |
| struct input_event fkey_ev; | |
| memset(&fkey_ev, 0, sizeof(fkey_ev)); | |
| fkey_ev.type = EV_KEY; | |
| fkey_ev.code = remapped_key; | |
| fkey_ev.value = 2; // repeat | |
| write(uinput_fd, &fkey_ev, sizeof(fkey_ev)); | |
| // Sync | |
| fkey_ev.type = EV_SYN; | |
| fkey_ev.code = SYN_REPORT; | |
| fkey_ev.value = 0; | |
| write(uinput_fd, &fkey_ev, sizeof(fkey_ev)); | |
| } else if (ie.value == 0) { // Key release | |
| // Send F-key release | |
| struct input_event fkey_ev; | |
| memset(&fkey_ev, 0, sizeof(fkey_ev)); | |
| fkey_ev.type = EV_KEY; | |
| fkey_ev.code = remapped_key; | |
| fkey_ev.value = 0; | |
| write(uinput_fd, &fkey_ev, sizeof(fkey_ev)); | |
| // Sync | |
| fkey_ev.type = EV_SYN; | |
| fkey_ev.code = SYN_REPORT; | |
| fkey_ev.value = 0; | |
| write(uinput_fd, &fkey_ev, sizeof(fkey_ev)); | |
| remapping_active = 0; // Re-enable normal forwarding | |
| } | |
| continue; // Don't forward the original key | |
| } | |
| } | |
| // Block AltGr events during remapping | |
| if (remapping_active && ie.type == EV_KEY && ie.code == KEY_RIGHTALT) { | |
| continue; // Don't forward AltGr during remapping | |
| } | |
| // Forward all other events | |
| write(uinput_fd, &ie, sizeof(ie)); | |
| } | |
| ioctl(input_fd, EVIOCGRAB, 0); | |
| ioctl(uinput_fd, UI_DEV_DESTROY); | |
| close(input_fd); | |
| close(uinput_fd); | |
| return 0; | |
| } | |
| ``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment