AFAIK, esto no se puede hacer sin Xlib (también conocido como X) sin permisos de nivel raíz. Usar XQueryKeymap() hará lo que quieras. sin embargo, señaló que X no se puede usar. Independientemente, también se requerirá abrir la conexión de la pantalla.
#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);
}
Creo que habría una manera de hacer esto. La cosa es que tendrías que leer directamente desde el dispositivo de teclado. No recibiría información de la terminal. Tengo el mismo problema. Tengo un programa que se ejecuta (en segundo plano) y quiero saber si el usuario mantiene presionada la tecla Mayús.
Creo que esto es posible y un lugar para comenzar podría ser /dev/input/by-path/*-kbd
.
Este archivo proporciona información cada vez que se presiona una tecla o repite si se mantiene presionada, por lo que podría valer la pena echarle un vistazo. (Prueba con el gato /dev/input/by-path/*-kbd
)
Si logras resolver esto, me encantaría saber cómo lo hiciste.
EDITAR:He encontrado la solución
He descubierto cómo hacer esto. Mi programa es el siguiente:
#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
}
Falta el mensaje de información (soy demasiado perezoso). Pero esencialmente, el primer argumento se compara con una lista de claves y se usa el identificador de clave apropiado. Devuelve verdadero si se presiona la tecla y falso si no.
Tenga en cuenta
Deberá cambiar el nombre del dispositivo de teclado. No conozco una forma de encontrar el dispositivo de teclado predeterminado. (si lo sabes me encantaría escuchar;) )
Esto funciona muy bien:lo uso para iniciar el inicio automático de Xorg si mantengo presionada la tecla Mayús.