AFAIK questo non può essere fatto senza Xlib (aka. X) senza permessi a livello di root. L'uso di XQueryKeymap() farà quello che vuoi. tuttavia hai sottolineato che X non può essere utilizzato. Indipendentemente da ciò, sarà richiesta anche l'apertura della connessione al display.
#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);
}
Penso che ci sarebbe un modo per farlo. Il fatto è che dovresti leggere direttamente dal dispositivo della tastiera. Non riceveresti input dal terminale. Ho lo stesso problema. Ho un programma in esecuzione (in background) e voglio sapere se l'utente sta tenendo premuto il tasto Maiusc.
Credo che questo sia possibile e un punto di partenza potrebbe essere /dev/input/by-path/*-kbd
.
Questo file fornisce input ogni volta che viene premuto un tasto o in modo ripetitivo se viene tenuto premuto, quindi potrebbe valere la pena dare un'occhiata. (Prova cat /dev/input/by-path/*-kbd
)
Se lo capisci, mi piacerebbe sapere come hai fatto.
EDIT:ho trovato la soluzione
Ho capito come farlo. Il mio programma è il seguente:
#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
}
Manca il messaggio informativo (sono troppo pigro). Ma essenzialmente il primo argomento viene confrontato con un elenco di chiavi e viene utilizzato l'identificatore di chiave appropriato. Restituisce vero se il tasto è premuto e falso in caso contrario.
Nota
Dovrai cambiare il nome del loro dispositivo tastiera. Non conosco un modo per trovare il dispositivo tastiera predefinito. (se sai che mi piacerebbe sentire;) )
Funziona magnificamente:lo uso per avviare l'avvio automatico di Xorg se tengo premuto il tasto Maiusc.