Comment obtenir Ctrl, Shift ou Alt avec getch () ncurses?

Comment obtenir Ctrl , Shift ou Alt avec getch() ncurses?
Je n’arrive pas à obtenir du travail pour obtenir Ctrl , Maj ou Alt avec getch() utilisant ncurses? Est-ce que quelque chose me manque chez l’homme?

C’est étonnant de constater que parfois la bonne réponse est rétrogradée et qu’un renoncement «autoritaire» est promu … Avec un peu de créativité, key_name détient en fait la clé pour le comprendre, avec une mise en garde: que SHIFT / ALT / CTRL appuyé avec d’autres touches en même temps:

  • Premièrement, pour les “touches normales” telles que celles imprimables, vous pouvez facilement détecter les décalages car ils sont en majuscules.

  • Pour les touches spéciales, par exemple KEY_LEFT, vous verrez que le code généré lorsque SHIFT est sélectionné est réellement KEY_SLEFT. idem pour KEY_RIGHT. Malheureusement, pas de chance pour KEY_UP / KEY_DOWN, qui semble ne pas être touché par SHIFT. Ainsi, vous pouvez distinguer par le caractère retourné de getch () – KEY_S .. implique que shift a été enfoncé.

  • Pour ALT (ce qui n’est pas piégé par X ou Aqua Windowmanager, au moins), keyname convertira la clé en M … quelque chose.

  • Pour CTRL, vous obtenez un “^” précédant le nom de la clé. Eg ^ R pour la clé 18

Ainsi, vous pouvez maintenant trouver les codes de clé pour vos instructions switch (getch), etc., par un simple extrait:

 ch = getch(); endwin(); printf("KEY NAME : %s - %d\n", keyname(ch),ch); 

et c’est ça. Réfléchissez avant de dire définitivement “ne peut pas”. Peut-être y a-t-il un moyen moins évident.

(Pour copier approximativement ma réponse de Comment obtenir les touches Maj + X / Alt + X dans Curses? )

Longue histoire courte – vous ne pouvez pas. Les touches de modification ne sont que cela – des modificateurs. Elles n’existent pas par elles-mêmes, elles modifient une autre touche (d’impression) sur laquelle vous pourriez appuyer.

Cela dit, si vous vous sentez particulièrement courageux, vous pouvez essayer ma clé libtermkey qui permettra au moins d’parsingr correctement des éléments tels que Ctrlflèche .

Enfin, si vous vous sentez encore plus courageux, vous pouvez utiliser le terminal que j’ai écrit, pangoterm , qui propose des méthodes génériques pour coder les clés Unicode modifiées de façon arbitraire. etc…

Cependant, en dehors de ceux-ci, la réponse rest “vous ne pouvez pas”.

Au moins pour le modificateur de contrôle, il existe une solution simple. Les malédictions ont été dérivées du code source de vi, dans lequel vous trouvez les éléments suivants (voir https://github.com/nt-roff/ex-1.1/blob/master/ex.h ligne 77 et https://github.com. /nt-roff/ex-1.1/blob/master/ex_vops.c ligne 445):

 #ifndef CTRL #define CTRL(c) ((c) & 037) #endif switch(getch()) { case CTRL('r'): /* key ctrl-r (ie ^R) pressed */ 

Dépend de utilisé inclut CTRL peut ou peut ne pas déjà été défini dans votre code.

En acceptant (partiellement) avec @leonerd, ncurses ne vous donnera ces clés que lorsqu’elles sont utilisées comme modificateurs d’autres clés (en ignorant le caractère d’ échappement ASCII que certaines personnes confondent avec la touche Alt ). Il est possible d’indiquer à certains périphériques spécifiques de donner ces informations (par exemple, la console Linux décrite dans console_ioctl (4) ), mais ce n’est pas un problème que ncurses résoudra pour vous.

Reportez-vous à la FAQ ncurses Comment puis-je utiliser des modificateurs de décalage ou de contrôle? pour une longue réponse.

Mais bref: ncurses ne vous dit pas si un modificateur donné a été utilisé (sauf dans des cas particuliers où il y avait des utilisations bien connues de shift ), mais ses descriptions de terminal fournissent plutôt les informations en:

  • en multipliant les touches de fonction réelles par des combinaisons de modificateurs de décalage et de contrôle, ou par
  • en utilisant des noms basés sur les touches de fonction de style PC de xterm (shift est 2, alt est 3, contrôle 5, etc.), pour fournir les informations.

Il existe deux approches car la première utilise un tableau de 60 touches de fonction au maximum (assez pour les combinaisons de contrôle et de décalage), tandis que l’autre utilise uniquement des noms définis par l’utilisateur .

Toutes ces clés modifiées donnent plusieurs octets; une application utilisant le keypad() (bien sûr) dans ncurses obtiendrait un numéro unique. Dans ce dernier cas, les codes clés sont déterminés lors de l’exécution.

Cela concerne principalement les touches spéciales ( touches de fonction, d’édition et de curseur). Pour les clés ordinaires, on peut supposer que keyname donne un comportement spécial, mais la lecture de la description ne le fait pas:

  • il rapporte les caractères de contrôle ASCII (ce que vous pouvez utiliser à l’aide de la macro iscntrl ), et
  • fait des hypothèses sur les méta (qui ne sont utiles que pour xterm , des terminaux que vous allez utiliser), et
  • n’offre aucune aide pour le modificateur de décalage .

Des terminaux … ont tous les informations de modificateur disponibles en interne, mais les terminaux ne disposent généralement pas d’un moyen de transmettre ces informations aux applications. xterm peut le faire en utilisant la ressource modifyOtherKeys ,

  modifyOtherKeys (class ModifyOtherKeys) Like modifyCursorKeys, tells xterm to construct an escape sequence for other keys (such as "2") when modified by Control-, Alt- or Meta-modifiers. This feature does not apply to function keys and well-defined keys such as ESC or the control keys. The default is "0": 0 disables this feature. 1 enables this feature for keys except for those with well- known behavior, eg, Tab, Backarrow and some special control character cases, eg, Control-Space to make a NUL. 2 enables this feature for keys including the exceptions listed. 

qui correspond à une séquence de contrôle, visible dans les séquences de contrôle XTerm :

 CSI > Ps; Ps m Set or reset resource-values used by xterm to decide whether to construct escape sequences holding information about the modifiers pressed with a given key. The first parameter iden- tifies the resource to set/reset. The second parameter is the value to assign to the resource. If the second parameter is omitted, the resource is reset to its initial value. Ps = 0 -> modifyKeyboard. Ps = 1 -> modifyCursorKeys. Ps = 2 -> modifyFunctionKeys. Ps = 4 -> modifyOtherKeys. 

mais (étant une fonctionnalité spécifique à xterm), il n’ya aucune raison de l’utiliser dans ncurses: cela compliquerait inutilement le getch .

Vous ne pouvez pas, il n’y a pas d’extension dans aucun des grands émulateurs de terminaux pour y parvenir.

Si vous utilisez un environnement X11, vous pouvez utiliser les fonctions X11 pour le récupérer, mais la question est tout à fait différente.

Vous pouvez appeler key_name( c ) pour transformer la clé générée par getch() en quelque chose qui vous indique l’état du modificateur ctrl.

Par exemple, ce code indique “^ R” si vous appuyez sur ctrl-r:

 while( true ) { char c = getch(); if ( ERR == c ) break; const char *name = key_name( c ); move( 2, 2 ); clear(); printw( "You entered: %s ", name ); refresh(); }