Comment get un access au niveau user aux touches de modification dans l'application console?

J'ai besoin d'avoir access à l'état de la touche de modification pour une application de console que j'écris (un éditeur personnalisé).

Y at-il des packages / libs / tout ce qui fournissent cet access?

J'ai bricolé ce qui suit de quelque part, mais cela ne fonctionne que si vous êtes root, et je ne veux pas vraiment jouer à la racine.

#include <iostream> #include <ssortingng> #include <stdio.h> #include <ssortingng.h> #include <stdlib.h> #include <termios.h> #include <fcntl.h> #include <linux/input.h> #include <unistd.h> #include <errno.h> int kbhit(void) { struct termios oldt, newt; int ch; int oldf; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~0000172 ; //~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); oldf = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); fcntl(STDIN_FILENO, F_SETFL, oldf); return ch; } enum MODKEYS { SHIFT_L = 1, SHIFT_R = 2, CTRL_L = 4, CTRL_R = 8, ALT_L = 16, ALT_R = 32, }; int chkmodifiers() { int mods=0,keyb,mask; char key_map[KEY_MAX/8 + 1]; // Create a byte array the size of the number of keys //event1 - got by inspecting /dev/input/... FILE *kbd = fopen("/dev/input/event1", "r"); if (kbd == NULL) { printf("(chkmodifiers) ERROR: %s\n", strerror(errno)); //permission - got to be root! return 0; } memset(key_map, 0, sizeof(key_map)); ioctl(fileno(kbd), EVIOCGKEY(sizeof(key_map)), key_map); // Fill the keymap with the current keyboard state keyb = key_map[KEY_LEFTSHIFT/8]; mask = 1 << (KEY_LEFTSHIFT % 8); if (keyb & mask) mods += SHIFT_L; keyb = key_map[KEY_RIGHTSHIFT/8]; mask = 1 << (KEY_RIGHTSHIFT % 8); if (keyb & mask) mods += SHIFT_R; keyb = key_map[KEY_LEFTCTRL/8]; mask = 1 << (KEY_LEFTCTRL % 8); if (keyb & mask) mods += CTRL_L; keyb = key_map[KEY_RIGHTCTRL/8]; mask = 1 << (KEY_RIGHTCTRL % 8); if (keyb & mask) mods += CTRL_R; keyb = key_map[KEY_LEFTALT/8]; mask = 1 << (KEY_LEFTALT % 8); if (keyb & mask) mods += ALT_L; keyb = key_map[KEY_RIGHTALT/8]; mask = 1 << (KEY_RIGHTALT % 8); if (keyb & mask) mods += ALT_R; return mods; } int main() { puts("Press a key!"); char ch=0; int n=0,m; while (ch != 'q') { n = kbhit(); if (n != -1) { m = chkmodifiers(); ch = (char)n; printf("You pressed '%c' [%d]\n", ch, n); if ((m & SHIFT_L) == SHIFT_L) printf(" .. and ls\n"); if ((m & SHIFT_R) == SHIFT_R) printf(" .. and rs\n"); if ((m & CTRL_L) == CTRL_L) printf(" .. and lc\n"); if ((m & CTRL_R) == CTRL_R) printf(" .. and rc\n"); if ((m & ALT_L) == ALT_L) printf(" .. and la\n"); if ((m & ALT_R) == ALT_R) printf(" .. and ra\n"); } } return 0; } 

Libtermkey , une bibliothèque d'input de touches de terminal qui reconnaît les keys spéciales (telles que les touches fléchées et les touches de fonction), y compris les touches «modifiées» comme Ctrl-Left .

Une autre option pourrait être d'améliorer la fonctionnalité du charme , une copy ncurses minimale.

Dans un terminal, il a toujours été très difficile d'avoir ce genre d'information. Vous ne pouvez get un "keycode" et, bien sûr, cela signifie différentes choses en fonction de la combinaison de l'OS, du keyboard et du terminal que vous utilisez.

Vous findez une list complète de ces keycode sur votre OS avec un appel à xmodmap .

 $ xmodmap -pke keycode 9 = Escape NoSymbol Escape keycode 10 = ampersand 1 ampersand 1 dead_caron dead_ogonek dead_caron dead_ogonek keycode 11 = eacute 2 eacute 2 asciitilde Eacute asciitilde Eacute [...] keycode 244 = XF86Battery NoSymbol XF86Battery keycode 245 = XF86Bluetooth NoSymbol XF86Bluetooth keycode 246 = XF86WLAN NoSymbol XF86WLAN keycode 247 = 

Et une list de tous les modificateurs value avec ceci:

 $ xmodmap xmodmap: up to 4 keys per modifier, (keycodes in parentheses): shift Shift_L (0x32), Shift_R (0x3e) lock Caps_Lock (0x42) control Control_L (0x25), Control_R (0x69) mod1 Alt_L (0x40), Meta_L (0xcd) mod2 Num_Lock (0x4d) mod3 mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf) mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb) 

Il y a quelques informations brutes dans la database terminfo ou plus polies dans l'API ncurses afin d'aider les développeurs de système à surmonter ce gâchis.

Si vous pouvez réutiliser un code source existant comme celui de nano , cela devrait vous faire gagner beaucoup de time. Jetez un oeil à la fonction "get_escape_seq_kbinput" pour voir ce que je veux dire.

Si vous avez juste besoin d'un support linux moderne, il est possible qu'un appel à keyname soit suffisant.