summaryrefslogtreecommitdiff
path: root/usr/src/cmd/loadkeys/dumpkeys.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/loadkeys/dumpkeys.c')
-rw-r--r--usr/src/cmd/loadkeys/dumpkeys.c441
1 files changed, 441 insertions, 0 deletions
diff --git a/usr/src/cmd/loadkeys/dumpkeys.c b/usr/src/cmd/loadkeys/dumpkeys.c
new file mode 100644
index 0000000000..b200d5c73a
--- /dev/null
+++ b/usr/src/cmd/loadkeys/dumpkeys.c
@@ -0,0 +1,441 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+#ifndef lint
+#ident "%Z%%M% %I% %E% SMI"
+#endif
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/kbd.h>
+#include <sys/kbio.h>
+#include <errno.h>
+
+typedef enum {
+ SM_INVALID, /* this shift mask is invalid for this keyboard */
+ SM_NORMAL, /* "normal", valid shift mask */
+ SM_NUMLOCK, /* "Num Lock" shift mask */
+ SM_UP /* "Up" shift mask */
+} smtype_t;
+
+typedef struct {
+ char *sm_name;
+ int sm_mask;
+ smtype_t sm_type;
+} smentry_t;
+
+
+smentry_t shiftmasks[] = {
+ { "base", 0, SM_NORMAL },
+ { "shift", SHIFTMASK, SM_NORMAL },
+ { "caps", CAPSMASK, SM_NORMAL },
+ { "ctrl", CTRLMASK, SM_NORMAL },
+ { "altg", ALTGRAPHMASK, SM_NORMAL },
+ { "numl", NUMLOCKMASK, SM_NUMLOCK },
+ { "up", UPMASK, SM_UP },
+};
+
+#define NSHIFTS (sizeof (shiftmasks) / sizeof (shiftmasks[0]))
+
+static void printentry(struct kiockeymap *kio);
+static void printchar(int character, int delim);
+
+/*ARGSUSED*/
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ register int kbdfd;
+ register int keystation;
+ register int shift;
+ int ktype;
+ struct kiockeymap keyentry[NSHIFTS];
+ register int allsame;
+
+ if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
+ perror("dumpkeys: /dev/kbd");
+ return (1);
+ }
+ if (ioctl(kbdfd, KIOCTYPE, &ktype) < 0) {
+ perror("dumpkeys: ioctl(KIOCTYPE)");
+ return (1);
+ }
+ /* if no keyboard detected, or ascii terminal, exit silently */
+ if (ktype == KB_ASCII || ktype < 0)
+ exit(0);
+
+ /*
+ * See which shift masks are valid for this keyboard.
+ * We do that by trying to get the entry for keystation 0 and that
+ * shift mask; if the "ioctl" fails, we assume it's because the shift
+ * mask is invalid.
+ */
+ for (shift = 0; shift < NSHIFTS; shift++) {
+ keyentry[shift].kio_tablemask =
+ shiftmasks[shift].sm_mask;
+ keyentry[shift].kio_station = 0;
+ if (ioctl(kbdfd, KIOCGKEY, &keyentry[shift]) < 0)
+ shiftmasks[shift].sm_type = SM_INVALID;
+ }
+
+ /*
+ * Loop until we get an EINVAL, so we don't have to know
+ * how big the table might be.
+ */
+ for (keystation = 0; ; keystation++) {
+ for (shift = 0; shift < NSHIFTS; shift++) {
+ if (shiftmasks[shift].sm_type != SM_INVALID) {
+ keyentry[shift].kio_tablemask =
+ shiftmasks[shift].sm_mask;
+ keyentry[shift].kio_station = keystation;
+ if (ioctl(kbdfd, KIOCGKEY,
+ &keyentry[shift]) < 0) {
+ if (errno == EINVAL)
+ return (0);
+ perror("dumpkeys: KIOCGKEY");
+ return (1);
+ }
+ }
+ }
+
+ (void) printf("key %d\t", keystation);
+
+ /*
+ * See if all the "normal" entries (all but the Num Lock and Up
+ * entries) are the same.
+ */
+ allsame = 1;
+ for (shift = 1; shift < NSHIFTS; shift++) {
+ if (shiftmasks[shift].sm_type == SM_NORMAL) {
+ if (keyentry[0].kio_entry
+ != keyentry[shift].kio_entry) {
+ allsame = 0;
+ break;
+ }
+ }
+ }
+
+ if (allsame) {
+ /*
+ * All of the "normal" entries are the same; just print
+ * "all".
+ */
+ (void) printf(" all ");
+ printentry(&keyentry[0]);
+ } else {
+ /*
+ * The normal entries aren't all the same; print them
+ * individually.
+ */
+ for (shift = 0; shift < NSHIFTS; shift++) {
+ if (shiftmasks[shift].sm_type == SM_NORMAL) {
+ (void) printf(" %s ",
+ shiftmasks[shift].sm_name);
+ printentry(&keyentry[shift]);
+ }
+ }
+ }
+ if (allsame && keyentry[0].kio_entry == HOLE) {
+ /*
+ * This key is a "hole"; if either the Num Lock or Up
+ * entry isn't a "hole", print it.
+ */
+ for (shift = 0; shift < NSHIFTS; shift++) {
+ switch (shiftmasks[shift].sm_type) {
+
+ case SM_NUMLOCK:
+ case SM_UP:
+ if (keyentry[shift].kio_entry
+ != HOLE) {
+ (void) printf(" %s ",
+ shiftmasks[shift].sm_name);
+ printentry(&keyentry[shift]);
+ }
+ break;
+ }
+ }
+ } else {
+ /*
+ * This entry isn't a "hole"; if the Num Lock entry
+ * isn't NONL (i.e, if Num Lock actually does
+ * something) print it, and if the Up entry isn't NOP
+ * (i.e., if up transitions on this key actually do
+ * something) print it.
+ */
+ for (shift = 0; shift < NSHIFTS; shift++) {
+ switch (shiftmasks[shift].sm_type) {
+
+ case SM_NUMLOCK:
+ if (keyentry[shift].kio_entry
+ != NONL) {
+ (void) printf(" %s ",
+ shiftmasks[shift].sm_name);
+ printentry(&keyentry[shift]);
+ }
+ break;
+
+ case SM_UP:
+ if (keyentry[shift].kio_entry
+ != NOP) {
+ (void) printf(" %s ",
+ shiftmasks[shift].sm_name);
+ printentry(&keyentry[shift]);
+ }
+ break;
+ }
+ }
+ }
+ (void) printf("\n");
+ }
+}
+
+static char *shiftkeys[] = {
+ "capslock",
+ "shiftlock",
+ "leftshift",
+ "rightshift",
+ "leftctrl",
+ "rightctrl",
+ "meta", /* not used */
+ "top", /* not used */
+ "cmd", /* reserved */
+ "altgraph",
+ "alt",
+ "numlock",
+};
+
+#define NSHIFTKEYS (sizeof (shiftkeys) / sizeof (shiftkeys[0]))
+
+static char *buckybits[] = {
+ "metabit",
+ "systembit",
+};
+
+#define NBUCKYBITS (sizeof (buckybits) / sizeof (buckybits[0]))
+
+static char *funnies[] = {
+ "nop",
+ "oops",
+ "hole",
+ "reset",
+ "error",
+ "idle",
+ "compose",
+ "nonl",
+};
+
+#define NFUNNIES (sizeof (funnies) / sizeof (funnies[0]))
+
+static char *fa_class[] = {
+ "fa_umlaut",
+ "fa_cflex",
+ "fa_tilde",
+ "fa_cedilla",
+ "fa_acute",
+ "fa_grave",
+};
+
+#define NFA_CLASS (sizeof (fa_class) / sizeof (fa_class[0]))
+
+typedef struct {
+ char *string;
+ char *name;
+} builtin_string_t;
+
+builtin_string_t builtin_strings[] = {
+ { "\033[H", "homearrow" },
+ { "\033[A", "uparrow" },
+ { "\033[B", "downarrow" },
+ { "\033[D", "leftarrow" },
+ { "\033[C", "rightarrow" },
+};
+
+#define NBUILTIN_STRINGS (sizeof (builtin_strings) / \
+ sizeof (builtin_strings[0]))
+
+static char *fkeysets[] = {
+ "lf",
+ "rf",
+ "tf",
+ "bf",
+};
+
+#define NFKEYSETS (sizeof (fkeysets) / sizeof (fkeysets[0]))
+
+static char *padkeys[] = {
+ "padequal",
+ "padslash",
+ "padstar",
+ "padminus",
+ "padsep",
+ "pad7",
+ "pad8",
+ "pad9",
+ "padplus",
+ "pad4",
+ "pad5",
+ "pad6",
+ "pad1",
+ "pad2",
+ "pad3",
+ "pad0",
+ "paddot",
+ "padenter",
+};
+
+#define NPADKEYS (sizeof (padkeys) / sizeof (padkeys[0]))
+
+static void
+printentry(kio)
+ register struct kiockeymap *kio;
+{
+ register int entry = (kio->kio_entry & 0x1F);
+ register int fkeyset;
+ register int i;
+ register int c;
+
+ switch (kio->kio_entry >> 8) {
+
+ case 0x0:
+ if (kio->kio_entry == '"')
+ (void) printf("'\"'"); /* special case */
+ else if (kio->kio_entry == ' ')
+ (void) printf("' '"); /* special case */
+ else
+ printchar((int)kio->kio_entry, '\'');
+ break;
+
+ case SHIFTKEYS >> 8:
+ if (entry < NSHIFTKEYS)
+ (void) printf("shiftkeys+%s", shiftkeys[entry]);
+ else
+ (void) printf("%#4x", kio->kio_entry);
+ break;
+
+ case BUCKYBITS >> 8:
+ if (entry < NBUCKYBITS)
+ (void) printf("buckybits+%s", buckybits[entry]);
+ else
+ (void) printf("%#4x", kio->kio_entry);
+ break;
+
+ case FUNNY >> 8:
+ if (entry < NFUNNIES)
+ (void) printf("%s", funnies[entry]);
+ else
+ (void) printf("%#4x", kio->kio_entry);
+ break;
+
+ case FA_CLASS >> 8:
+ if (entry < NFA_CLASS)
+ (void) printf("%s", fa_class[entry]);
+ else
+ (void) printf("%#4x", kio->kio_entry);
+ break;
+
+ case STRING >> 8:
+ if (entry < NBUILTIN_STRINGS && strncmp(kio->kio_string,
+ builtin_strings[entry].string, KTAB_STRLEN) == 0)
+ (void) printf("string+%s", builtin_strings[entry].name);
+ else {
+ (void) printf("\"");
+ for (i = 0;
+ i < KTAB_STRLEN && (c = kio->kio_string[i]) != '\0';
+ i++)
+ printchar(c, '"');
+ (void) printf("\"");
+ }
+ break;
+
+ case FUNCKEYS >> 8:
+ fkeyset = (int)(kio->kio_entry & 0xF0) >> 4;
+ if (fkeyset < NFKEYSETS)
+ (void) printf("%s(%d)", fkeysets[fkeyset],
+ (entry&0x0F) + 1);
+ else
+ (void) printf("%#4x", kio->kio_entry);
+ break;
+
+ case PADKEYS >> 8:
+ if (entry < NPADKEYS)
+ (void) printf("%s", padkeys[entry]);
+ else
+ (void) printf("%#4x", kio->kio_entry);
+ break;
+
+ default:
+ (void) printf("%#4x", kio->kio_entry);
+ break;
+ }
+}
+
+static void
+printchar(character, delim)
+ int character;
+ int delim;
+{
+ switch (character) {
+
+ case '\n':
+ (void) printf("'\\n'");
+ break;
+
+ case '\t':
+ (void) printf("'\\t'");
+ break;
+
+ case '\b':
+ (void) printf("'\\b'");
+ break;
+
+ case '\r':
+ (void) printf("'\\r'");
+ break;
+
+ case '\v':
+ (void) printf("'\\v'");
+ break;
+
+ case '\\':
+ (void) printf("'\\\\'");
+ break;
+
+ default:
+ if (isprint(character)) {
+ if (character == delim)
+ (void) printf("'\\'");
+ (void) printf("%c", character);
+ } else {
+ if (character < 040)
+ (void) printf("^%c", character + 0100);
+ else
+ (void) printf("'\\%.3o'", character);
+ }
+ break;
+ }
+}