Il y a des fois, je me dis que l'association GNU/Linux + X ne fait clairement pas le poids face à Windows. Oui, je sais, c'est un troll, j'assume parfaitement. Je m'explique : je cherche, stupidement, à détecter l'état à un instant donné de la touche CapsLock de mon clavier. Je ne VEUX PAS le faire dans une boucle évènementielle genre sur un keypress, et tester à ce moment-là. J'ai besoin d'exécuter ce code à tout moment, indépendemment de tout évènement. Cela donne donc quelque chose comme ça:

  int fd;
  long int keysState;

  /* To use as the fd in ioctl(). */
  if ((fd = open("/dev/tty", O_NOCTTY)) == ERROR) 
  {
    close(fd);
    exit;
  }

  /* Value stored in arg. */
  if (ioctl(fd, KDGKBLED, &keysState) == ERROR) 
  {
    close(fd);
    exit;
  }

  if (keysState & K_CAPSLOCK)
  {
    // caps lock key is on
  }
  else
  {
    // caps lock key is off
  }

Mais ça, qui semble être la seule manière de faire, NE MARCHE PAS parce que X bloque l'accès non-root à /dev/tty ou /dev/console. Bref, sans avoir les droits de root, impossible pour un logiciel de connaître l'état de la touche CAPS-LOCK hors d'une boucle évènementielle. Est-ce que je me trompe ou c'est vraiment hyper-foireux/lamentable à ce point-là ?!?

Ah au fait, sur Windows, il suffit d'écrire ce qui suit, et bien entendu, pas besoin de privilèges spéciaux pour l'exécuter:

  SHORT st = GetKeyState(20);
  if (st & 1)
  {
    // caps lock key is on
  }
  else
  {
    // caps lock key is off
  }

UPDATE: solution provided by kolter in the comments.