Merge commit 'a058d1cc571af5fbcfe7f1d719df1abbfdb722f3' into merges
[unleashed.git] / usr / src / cmd / loadkeys / dumpkeys.c
blobb6df699c998ed865a67421ffed9458b302401d7d
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
22 #ident "%Z%%M% %I% %E% SMI"
25 * Copyright (c) 1988 by Sun Microsystems, Inc.
28 #include <sys/types.h>
29 #include <ctype.h>
30 #include <stdio.h>
31 #include <fcntl.h>
32 #include <sys/kbd.h>
33 #include <sys/kbio.h>
34 #include <errno.h>
36 typedef enum {
37 SM_INVALID, /* this shift mask is invalid for this keyboard */
38 SM_NORMAL, /* "normal", valid shift mask */
39 SM_NUMLOCK, /* "Num Lock" shift mask */
40 SM_UP /* "Up" shift mask */
41 } smtype_t;
43 typedef struct {
44 char *sm_name;
45 int sm_mask;
46 smtype_t sm_type;
47 } smentry_t;
50 smentry_t shiftmasks[] = {
51 { "base", 0, SM_NORMAL },
52 { "shift", SHIFTMASK, SM_NORMAL },
53 { "caps", CAPSMASK, SM_NORMAL },
54 { "ctrl", CTRLMASK, SM_NORMAL },
55 { "altg", ALTGRAPHMASK, SM_NORMAL },
56 { "numl", NUMLOCKMASK, SM_NUMLOCK },
57 { "up", UPMASK, SM_UP },
60 #define NSHIFTS (sizeof (shiftmasks) / sizeof (shiftmasks[0]))
62 static void printentry(struct kiockeymap *kio);
63 static void printchar(int character, int delim);
65 /*ARGSUSED*/
66 int
67 main(argc, argv)
68 int argc;
69 char **argv;
71 register int kbdfd;
72 register int keystation;
73 register int shift;
74 int ktype;
75 struct kiockeymap keyentry[NSHIFTS];
76 register int allsame;
78 if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
79 perror("dumpkeys: /dev/kbd");
80 return (1);
82 if (ioctl(kbdfd, KIOCTYPE, &ktype) < 0) {
83 perror("dumpkeys: ioctl(KIOCTYPE)");
84 return (1);
86 /* if no keyboard detected, or ascii terminal, exit silently */
87 if (ktype == KB_ASCII || ktype < 0)
88 exit(0);
91 * See which shift masks are valid for this keyboard.
92 * We do that by trying to get the entry for keystation 0 and that
93 * shift mask; if the "ioctl" fails, we assume it's because the shift
94 * mask is invalid.
96 for (shift = 0; shift < NSHIFTS; shift++) {
97 keyentry[shift].kio_tablemask =
98 shiftmasks[shift].sm_mask;
99 keyentry[shift].kio_station = 0;
100 if (ioctl(kbdfd, KIOCGKEY, &keyentry[shift]) < 0)
101 shiftmasks[shift].sm_type = SM_INVALID;
105 * Loop until we get an EINVAL, so we don't have to know
106 * how big the table might be.
108 for (keystation = 0; ; keystation++) {
109 for (shift = 0; shift < NSHIFTS; shift++) {
110 if (shiftmasks[shift].sm_type != SM_INVALID) {
111 keyentry[shift].kio_tablemask =
112 shiftmasks[shift].sm_mask;
113 keyentry[shift].kio_station = keystation;
114 if (ioctl(kbdfd, KIOCGKEY,
115 &keyentry[shift]) < 0) {
116 if (errno == EINVAL)
117 return (0);
118 perror("dumpkeys: KIOCGKEY");
119 return (1);
124 (void) printf("key %d\t", keystation);
127 * See if all the "normal" entries (all but the Num Lock and Up
128 * entries) are the same.
130 allsame = 1;
131 for (shift = 1; shift < NSHIFTS; shift++) {
132 if (shiftmasks[shift].sm_type == SM_NORMAL) {
133 if (keyentry[0].kio_entry
134 != keyentry[shift].kio_entry) {
135 allsame = 0;
136 break;
141 if (allsame) {
143 * All of the "normal" entries are the same; just print
144 * "all".
146 (void) printf(" all ");
147 printentry(&keyentry[0]);
148 } else {
150 * The normal entries aren't all the same; print them
151 * individually.
153 for (shift = 0; shift < NSHIFTS; shift++) {
154 if (shiftmasks[shift].sm_type == SM_NORMAL) {
155 (void) printf(" %s ",
156 shiftmasks[shift].sm_name);
157 printentry(&keyentry[shift]);
161 if (allsame && keyentry[0].kio_entry == HOLE) {
163 * This key is a "hole"; if either the Num Lock or Up
164 * entry isn't a "hole", print it.
166 for (shift = 0; shift < NSHIFTS; shift++) {
167 switch (shiftmasks[shift].sm_type) {
169 case SM_NUMLOCK:
170 case SM_UP:
171 if (keyentry[shift].kio_entry
172 != HOLE) {
173 (void) printf(" %s ",
174 shiftmasks[shift].sm_name);
175 printentry(&keyentry[shift]);
177 break;
180 } else {
182 * This entry isn't a "hole"; if the Num Lock entry
183 * isn't NONL (i.e, if Num Lock actually does
184 * something) print it, and if the Up entry isn't NOP
185 * (i.e., if up transitions on this key actually do
186 * something) print it.
188 for (shift = 0; shift < NSHIFTS; shift++) {
189 switch (shiftmasks[shift].sm_type) {
191 case SM_NUMLOCK:
192 if (keyentry[shift].kio_entry
193 != NONL) {
194 (void) printf(" %s ",
195 shiftmasks[shift].sm_name);
196 printentry(&keyentry[shift]);
198 break;
200 case SM_UP:
201 if (keyentry[shift].kio_entry
202 != NOP) {
203 (void) printf(" %s ",
204 shiftmasks[shift].sm_name);
205 printentry(&keyentry[shift]);
207 break;
211 (void) printf("\n");
215 static char *shiftkeys[] = {
216 "capslock",
217 "shiftlock",
218 "leftshift",
219 "rightshift",
220 "leftctrl",
221 "rightctrl",
222 "meta", /* not used */
223 "top", /* not used */
224 "cmd", /* reserved */
225 "altgraph",
226 "alt",
227 "numlock",
230 #define NSHIFTKEYS (sizeof (shiftkeys) / sizeof (shiftkeys[0]))
232 static char *buckybits[] = {
233 "metabit",
234 "systembit",
237 #define NBUCKYBITS (sizeof (buckybits) / sizeof (buckybits[0]))
239 static char *funnies[] = {
240 "nop",
241 "oops",
242 "hole",
243 "reset",
244 "error",
245 "idle",
246 "compose",
247 "nonl",
250 #define NFUNNIES (sizeof (funnies) / sizeof (funnies[0]))
252 static char *fa_class[] = {
253 "fa_umlaut",
254 "fa_cflex",
255 "fa_tilde",
256 "fa_cedilla",
257 "fa_acute",
258 "fa_grave",
261 #define NFA_CLASS (sizeof (fa_class) / sizeof (fa_class[0]))
263 typedef struct {
264 char *string;
265 char *name;
266 } builtin_string_t;
268 builtin_string_t builtin_strings[] = {
269 { "\033[H", "homearrow" },
270 { "\033[A", "uparrow" },
271 { "\033[B", "downarrow" },
272 { "\033[D", "leftarrow" },
273 { "\033[C", "rightarrow" },
276 #define NBUILTIN_STRINGS (sizeof (builtin_strings) / \
277 sizeof (builtin_strings[0]))
279 static char *fkeysets[] = {
280 "lf",
281 "rf",
282 "tf",
283 "bf",
286 #define NFKEYSETS (sizeof (fkeysets) / sizeof (fkeysets[0]))
288 static char *padkeys[] = {
289 "padequal",
290 "padslash",
291 "padstar",
292 "padminus",
293 "padsep",
294 "pad7",
295 "pad8",
296 "pad9",
297 "padplus",
298 "pad4",
299 "pad5",
300 "pad6",
301 "pad1",
302 "pad2",
303 "pad3",
304 "pad0",
305 "paddot",
306 "padenter",
309 #define NPADKEYS (sizeof (padkeys) / sizeof (padkeys[0]))
311 static void
312 printentry(kio)
313 register struct kiockeymap *kio;
315 register int entry = (kio->kio_entry & 0x1F);
316 register int fkeyset;
317 register int i;
318 register int c;
320 switch (kio->kio_entry >> 8) {
322 case 0x0:
323 if (kio->kio_entry == '"')
324 (void) printf("'\"'"); /* special case */
325 else if (kio->kio_entry == ' ')
326 (void) printf("' '"); /* special case */
327 else
328 printchar((int)kio->kio_entry, '\'');
329 break;
331 case SHIFTKEYS >> 8:
332 if (entry < NSHIFTKEYS)
333 (void) printf("shiftkeys+%s", shiftkeys[entry]);
334 else
335 (void) printf("%#4x", kio->kio_entry);
336 break;
338 case BUCKYBITS >> 8:
339 if (entry < NBUCKYBITS)
340 (void) printf("buckybits+%s", buckybits[entry]);
341 else
342 (void) printf("%#4x", kio->kio_entry);
343 break;
345 case FUNNY >> 8:
346 if (entry < NFUNNIES)
347 (void) printf("%s", funnies[entry]);
348 else
349 (void) printf("%#4x", kio->kio_entry);
350 break;
352 case FA_CLASS >> 8:
353 if (entry < NFA_CLASS)
354 (void) printf("%s", fa_class[entry]);
355 else
356 (void) printf("%#4x", kio->kio_entry);
357 break;
359 case STRING >> 8:
360 if (entry < NBUILTIN_STRINGS && strncmp(kio->kio_string,
361 builtin_strings[entry].string, KTAB_STRLEN) == 0)
362 (void) printf("string+%s", builtin_strings[entry].name);
363 else {
364 (void) printf("\"");
365 for (i = 0;
366 i < KTAB_STRLEN && (c = kio->kio_string[i]) != '\0';
367 i++)
368 printchar(c, '"');
369 (void) printf("\"");
371 break;
373 case FUNCKEYS >> 8:
374 fkeyset = (int)(kio->kio_entry & 0xF0) >> 4;
375 if (fkeyset < NFKEYSETS)
376 (void) printf("%s(%d)", fkeysets[fkeyset],
377 (entry&0x0F) + 1);
378 else
379 (void) printf("%#4x", kio->kio_entry);
380 break;
382 case PADKEYS >> 8:
383 if (entry < NPADKEYS)
384 (void) printf("%s", padkeys[entry]);
385 else
386 (void) printf("%#4x", kio->kio_entry);
387 break;
389 default:
390 (void) printf("%#4x", kio->kio_entry);
391 break;
395 static void
396 printchar(character, delim)
397 int character;
398 int delim;
400 switch (character) {
402 case '\n':
403 (void) printf("'\\n'");
404 break;
406 case '\t':
407 (void) printf("'\\t'");
408 break;
410 case '\b':
411 (void) printf("'\\b'");
412 break;
414 case '\r':
415 (void) printf("'\\r'");
416 break;
418 case '\v':
419 (void) printf("'\\v'");
420 break;
422 case '\\':
423 (void) printf("'\\\\'");
424 break;
426 default:
427 if (isprint(character)) {
428 if (character == delim)
429 (void) printf("'\\'");
430 (void) printf("%c", character);
431 } else {
432 if (character < 040)
433 (void) printf("^%c", character + 0100);
434 else
435 (void) printf("'\\%.3o'", character);
437 break;