AFAIK, cela ne peut pas être fait sans Xlib (aka. X) sans autorisations au niveau racine. L'utilisation de XQueryKeymap() fera ce que vous voulez. cependant, vous avez souligné que X ne peut pas être utilisé. Quoi qu'il en soit, l'ouverture de la connexion d'affichage sera également nécessaire.
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <stdbool.h>
#include <stdio.h>
int main()
{
Display* dpy = XOpenDisplay(NULL);
char keys_return[32];
XQueryKeymap( dpy, keys_return );
KeyCode kc2 = XKeysymToKeycode( dpy, XK_Shift_L );
bool bShiftPressed = !!( keys_return[ kc2>>3 ] & ( 1<<(kc2&7) ) );
printf("Shift is %spressed\n", bShiftPressed ? "" : "not ");
XCloseDisplay(dpy);
}
Je pense qu'il y aurait un moyen de le faire. Le fait est que vous auriez à lire directement à partir du clavier. Vous n'obtiendriez pas d'entrée du terminal. J'ai le même problème. J'ai un programme qui s'exécute (en arrière-plan) et je veux savoir si l'utilisateur maintient la touche Maj enfoncée.
Je crois que c'est possible et un point de départ pourrait être /dev/input/by-path/*-kbd
.
Ce fichier donne une entrée à chaque fois qu'une touche est enfoncée ou reptadly si elle est maintenue enfoncée, il peut donc valoir la peine d'être regardé. (Essayez le chat /dev/input/by-path/*-kbd
)
Si vous comprenez cela, j'aimerais savoir comment vous l'avez fait.
EDIT :j'ai trouvé la solution
J'ai compris comment faire cela. Mon programme est le suivant :
#include <stdlib.h>
#include <stdio.h>
#include <linux/input.h>
void usage ( int argc, char *argv[] )
{
printf("Usage:\n\t%s key\n\nvalid keys are:\n\tlshift\t- Left Shift key\n" , argv[0]);
exit(EXIT_FAILURE);
}
int main ( int argc, char *argv[], char *env[] )
{
if ( argc != 2 ) usage(argc, argv);
int key;
if ( strcmp(argv[1], "lshift") == 0 ) key = KEY_LEFTSHIFT;
else if ( strcmp(argv[1], "rshift") == 0 ) key = KEY_RIGHTSHIFT;
else if ( strcmp(argv[1], "lalt") == 0 ) key = KEY_LEFTALT;
else if ( strcmp(argv[1], "ralt") == 0 ) key = KEY_RIGHTALT;
else if ( strcmp(argv[1], "lctrl") == 0 ) key = KEY_LEFTCTRL;
else if ( strcmp(argv[1], "rctrl") == 0 ) key = KEY_RIGHTCTRL;
FILE *kbd = fopen("/dev/input/by-path/platform-i8042-serio-0-event-kbd", "r");
char key_map[KEY_MAX/8 + 1]; // Create a byte array the size of the number of keys
memset(key_map, 0, sizeof(key_map)); // Initate the array to zero's
ioctl(fileno(kbd), EVIOCGKEY(sizeof(key_map)), key_map); // Fill the keymap with the current keyboard state
int keyb = key_map[key/8]; // The key we want (and the seven others arround it)
int mask = 1 << (key % 8); // Put a one in the same column as out key state will be in;
return !(keyb & mask); // Returns true if pressed otherwise false
}
Le message d'information manque (je suis trop paresseux). Mais essentiellement, le premier argument est comparé à une liste de clés et l'identifiant de clé approprié est utilisé. Il renvoie vrai si la touche est enfoncée et faux sinon.
Veuillez noter
Vous devrez changer le nom de leur clavier. Je ne connais pas de moyen de trouver le périphérique de clavier par défaut. (si vous savez, j'aimerais entendre ;) )
Cela fonctionne à merveille :je l'utilise pour démarrer le démarrage automatique de Xorg si je maintiens la touche Maj enfoncée.