kbdinfo: Add new utility to obtain information about console
authorAlexey Gladkov <gladkov.alexey@gmail.com>
Tue, 29 Mar 2011 22:20:56 +0000 (02:20 +0400)
committerAlexey Gladkov <gladkov.alexey@gmail.com>
Tue, 29 Mar 2011 22:20:56 +0000 (02:20 +0400)
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
COPYING
src/Makefile.am
src/kbdinfo.c [new file with mode: 0644]

diff --git a/COPYING b/COPYING
index 46f4eba..c8e0497 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -28,6 +28,10 @@ The files
 (and changes to earlier mentioned programs)
 are Copyright (C) 1994-1999 Andries E. Brouwer.
 
+The file
+       kbdinfo.c
+is Copyright (C) 2011 Alexey Gladkov.
+
 All files in this package may be freely copied under the terms
 of the GNU General Public License (GPL), version 2, or at your
 option any later version - except possibly for the restrictions
index 7e2cadb..fbdfff4 100644 (file)
@@ -9,7 +9,7 @@ OLDPROGS = mapscrn loadunimap
 PROGS = \
        dumpkeys loadkeys showkey setfont showconsolefont \
        setleds setmetamode kbd_mode psfxtable fgconsole \
-       kbdrate chvt deallocvt openvt
+       kbdrate chvt deallocvt openvt kbdinfo
 
 if KEYCODES_PROGS
 PROGS += getkeycodes setkeycodes
@@ -65,6 +65,7 @@ setpalette_SOURCES      = $(ALL_S) setpalette.c $(GETFD_S)
 setvesablank_SOURCES    = $(ALL_S) setvesablank.c $(GETFD_S)
 showconsolefont_SOURCES = $(ALL_S) showconsolefont.c $(GETFD_S) $(XMAL_S) $(KDMA_S) kdfontop.c kdfontop.h
 showkey_SOURCES         = $(ALL_S) showkey.c $(GETFD_S)
+kbdinfo_SOURCES         = $(ALL_S) kbdinfo.c $(GETFD_S)
 
 mapscrn_CFLAGS = -DMAIN
 loadunimap_CFLAGS = -DMAIN
diff --git a/src/kbdinfo.c b/src/kbdinfo.c
new file mode 100644 (file)
index 0000000..1df241a
--- /dev/null
@@ -0,0 +1,127 @@
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/kd.h>
+#include <getopt.h>
+#include "getfd.h"
+#include "nls.h"
+#include "version.h"
+
+static const char *action = NULL;
+static const char *value  = NULL;
+
+static void attr_noreturn
+usage(int code) {
+       fprintf(stderr, _("Usage: %s [-C DEVICE] getmode [text|graphics]\n"), progname);
+       fprintf(stderr, _("   or: %s [-C DEVICE] gkbmode [raw|xlate|mediumraw|unicode]\n"), progname);
+       fprintf(stderr, _("   or: %s [-C DEVICE] gkbmeta [metabit|escprefix]\n"), progname);
+       fprintf(stderr, _("   or: %s [-C DEVICE] gkbled  [scrolllock|numlock|capslock]\n"), progname);
+       exit(code);
+}
+
+static int
+answer(const char *ans) {
+       if (value)
+               return strcasecmp(value, ans) ? EXIT_FAILURE : EXIT_SUCCESS;
+
+       printf("%s\n", ans);
+       return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char **argv) {
+       int fd, mode, c;
+       int rc = EXIT_FAILURE;
+       char flags;
+       const char *console = NULL;
+
+       set_progname(argv[0]);
+
+       setlocale(LC_ALL, "");
+       bindtextdomain(PACKAGE_NAME, LOCALEDIR);
+       textdomain(PACKAGE_NAME);
+
+       while ((c = getopt(argc, argv, "C:hV")) != EOF) {
+               switch (c) {
+                       case 'C':
+                               if (optarg == NULL || optarg[0] == '\0')
+                                       usage(EXIT_FAILURE);
+                               console = optarg;
+                               break;
+                       case 'V':
+                               print_version_and_exit();
+                               break;
+                       case 'h':
+                               usage(EXIT_SUCCESS);
+                               break;
+               }
+       }
+
+       if (optind == argc) {
+               fprintf(stderr, _("Error: Not enough arguments.\n"));
+               exit(EXIT_FAILURE);
+       }
+
+       action = argv[optind++];
+
+       if (optind < argc)
+               value = argv[optind++];
+
+       fd = getfd(console);
+
+       if (!strcasecmp("GETMODE", action)) {
+               if (ioctl(fd, KDGETMODE, &mode) == -1)
+                       error(EXIT_FAILURE, errno, "ioctl");
+
+               switch (mode) {
+                       case KD_TEXT:           rc = answer("text");            break;
+                       case KD_GRAPHICS:       rc = answer("graphics");        break;
+               }
+
+       } else if (!strcasecmp("GKBMODE", action)) {
+               if (ioctl(fd, KDGKBMODE, &mode) == -1)
+                       error(EXIT_FAILURE, errno, "ioctl");
+
+               switch (mode) {
+                       case K_RAW:             rc = answer("raw");             break;
+                       case K_XLATE:           rc = answer("xlate");           break;
+                       case K_MEDIUMRAW:       rc = answer("mediumraw");       break;
+                       case K_UNICODE:         rc = answer("unicode");         break;
+               }
+
+       } else if (!strcasecmp("GKBMETA", action)) {
+               if (ioctl(fd, KDGKBMETA, &mode) == -1)
+                       error(EXIT_FAILURE, errno, "ioctl");
+
+               switch (mode) {
+                       case K_METABIT:         rc = answer("metabit");         break;
+                       case K_ESCPREFIX:       rc = answer("escprefix");       break;
+               }
+
+       } else if (!strcasecmp("GKBLED", action)) {
+               if (ioctl(fd, KDGKBLED, &flags) == -1)
+                       error(EXIT_FAILURE, errno, "ioctl");
+
+               mode = (flags & 0x7);
+
+               if (value) {
+                       if (((mode & LED_SCR) && !strcasecmp(value, "scrolllock")) ||
+                           ((mode & LED_NUM) && !strcasecmp(value, "numlock"))    ||
+                           ((mode & LED_CAP) && !strcasecmp(value, "capslock")))
+                               rc = EXIT_SUCCESS;
+               } else {
+                       printf("scrolllock:%s ", (mode & LED_SCR) ? "on" : "off");
+                       printf("numlock:%s ",    (mode & LED_NUM) ? "on" : "off");
+                       printf("capslock:%s\n",  (mode & LED_CAP) ? "on" : "off");
+                       rc = EXIT_SUCCESS;
+               }
+
+       } else {
+               fprintf(stderr, _("Error: Unrecognized action: %s\n"), action);
+       }
+
+       close(fd);
+       return rc;
+}