From 4753f57f1c3f827e76d99252f0c2a006d29bf58e Mon Sep 17 00:00:00 2001 From: Aaron LI Date: Sun, 7 Oct 2018 21:49:05 +0800 Subject: [PATCH] Use ioctl 'KDGKBLED' on Linux The legacy ioctl 'KDGETLED' (which also exists on BSD) is used to get the state of keyboard LEDs, which, however, can be used to display arbitrary information! So the new ioctl 'KDGKBLED' should be used to get the keyboard flags (CapsLock, NumLock, ScrollLock), and this ioctl has a separate set of macros ('K_NUMLOCK', 'K_CAPSLOCK') to check the flags. See the ioctl_console(2) man page for more details. --- src/draw.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/draw.c b/src/draw.c index b0c53df..bd556a8 100644 --- a/src/draw.c +++ b/src/draw.c @@ -4,6 +4,7 @@ #include "util.h" #include "config.h" #include "widgets.h" + #include #include #include @@ -11,6 +12,8 @@ #include #include #include +#include +#include #include #if defined(__DragonFly__) || defined(__FreeBSD__) # include @@ -212,22 +215,33 @@ void draw_f_commands() // numlock and capslock info void draw_lock_state() { - FILE* console = fopen(config.console_dev, "r"); - - if (console == NULL) + int fd; + if ((fd = open(config.console_dev, O_RDONLY)) < 0) { info_line = lang.err_console_dev; return; } - int fd = fileno(console); - char led; + bool numlock_on; + bool capslock_on; + +#if defined(__DragonFly__) || defined(__FreeBSD__) + int led; ioctl(fd, KDGETLED, &led); - fclose(console); + numlock_on = led & LED_NUM; + capslock_on = led & LED_CAP; +#else /* Linux */ + char led; + ioctl(fd, KDGKBLED, &led); + numlock_on = led & K_NUMLOCK; + capslock_on = led & K_CAPSLOCK; +#endif + + close(fd); u16 pos_x = width - strlen(lang.numlock); - if (led & LED_NUM) + if (numlock_on) { struct tb_cell* numlock = str_cell(lang.numlock); tb_blit(pos_x, 0, strlen(lang.numlock), 1, numlock); @@ -236,7 +250,7 @@ void draw_lock_state() pos_x -= strlen(lang.capslock) + 1; - if (led & LED_CAP) + if (capslock_on) { struct tb_cell* capslock = str_cell(lang.capslock); tb_blit(pos_x, 0, strlen(lang.capslock), 1, capslock);